SQLite4
Check-in [6666862302]
Not logged in

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

Overview
Comment:Merge trunk changes into this branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | mmap-on-demand
Files: files | file ages | folders
SHA1: 6666862302f019b9253caef4104f9337d05d0a0e
User & Date: dan 2013-03-02 09:15:12
Context
2013-03-02
16:01
Fix some problems on this branch. Leaf check-in: a92d659eee user: dan tags: mmap-on-demand
09:15
Merge trunk changes into this branch. check-in: 6666862302 user: dan tags: mmap-on-demand
09:09
Remove a couple of unused variables from sqltest.c. check-in: e423d6c4bc user: dan tags: trunk
2013-02-05
09:51
Fix bugs on this branch. check-in: 0cbb5cc2cd user: dan tags: mmap-on-demand
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to lsm-test/lsmtest_func.c.

     3      3   
     4      4   
     5      5   int do_work(int nArg, char **azArg){
     6      6     struct Option {
     7      7       const char *zName;
     8      8     } aOpt [] = {
     9      9       { "-nmerge" },
    10         -    { "-npage" },
           10  +    { "-nkb" },
    11     11       { 0 }
    12     12     };
    13     13   
    14     14     lsm_db *pDb;
    15     15     int rc;
    16     16     int i;
    17     17     const char *zDb;
    18     18     int nMerge = 1;
    19         -  int nWork = (1<<30);
           19  +  int nKB = (1<<30);
    20     20   
    21     21     if( nArg==0 ) goto usage;
    22     22     zDb = azArg[nArg-1];
    23     23     for(i=0; i<(nArg-1); i++){
    24     24       int iSel;
    25     25       rc = testArgSelect(aOpt, "option", azArg[i], &iSel);
    26     26       if( rc ) return rc;
................................................................................
    29     29           i++;
    30     30           if( i==(nArg-1) ) goto usage;
    31     31           nMerge = atoi(azArg[i]);
    32     32           break;
    33     33         case 1:
    34     34           i++;
    35     35           if( i==(nArg-1) ) goto usage;
    36         -        nWork = atoi(azArg[i]);
           36  +        nKB = atoi(azArg[i]);
    37     37           break;
    38     38       }
    39     39     }
    40     40   
    41     41     rc = lsm_new(0, &pDb);
    42     42     if( rc!=LSM_OK ){
    43     43       testPrintError("lsm_open(): rc=%d\n", rc);
................................................................................
    47     47         testPrintError("lsm_open(): rc=%d\n", rc);
    48     48       }else{
    49     49         int n = -1;
    50     50         lsm_config(pDb, LSM_CONFIG_BLOCK_SIZE, &n);
    51     51         n = n*2;
    52     52         lsm_config(pDb, LSM_CONFIG_AUTOCHECKPOINT, &n);
    53     53   
    54         -      rc = lsm_work(pDb, nMerge, nWork, 0);
           54  +      rc = lsm_work(pDb, nMerge, nKB, 0);
    55     55         if( rc!=LSM_OK ){
    56     56           testPrintError("lsm_work(): rc=%d\n", rc);
    57     57         }
    58     58       }
    59     59     }
    60     60     if( rc==LSM_OK ){
    61     61       rc = lsm_checkpoint(pDb, 0);

Changes to lsm-test/lsmtest_main.c.

   563    563   "Options are:\n"
   564    564   "  -repeat  $repeat                 (default value 10)\n"
   565    565   "  -write   $write                  (default value 10000)\n"
   566    566   "  -pause   $pause                  (default value 0)\n"
   567    567   "  -fetch   $fetch                  (default value 0)\n"
   568    568   "  -keysize $keysize                (default value 12)\n"
   569    569   "  -valsize $valsize                (default value 100)\n"
   570         -"  -system  $system                 (default value \"lsm\"\n"
          570  +"  -system  $system                 (default value \"lsm\")\n"
   571    571   "\n"
   572    572   );
   573    573   }
   574    574   
   575    575   int do_speed_test2(int nArg, char **azArg){
   576    576     struct Option {
   577    577       const char *zOpt;
................................................................................
   642    642     }
   643    643     
   644    644     printf("#");
   645    645     for(i=0; i<ArraySize(aOpt); i++){
   646    646       if( aOpt[i].zOpt ){
   647    647         if( aOpt[i].eVal>=0 ){
   648    648           printf(" %s=%d", &aOpt[i].zOpt[1], aParam[aOpt[i].eVal]);
   649         -      }else{
          649  +      }else if( aOpt[i].eVal==-1 ){
   650    650           printf(" %s=\"%s\"", &aOpt[i].zOpt[1], zSystem);
   651    651         }
   652    652       }
   653    653     }
   654    654     printf("\n");
   655    655   
   656    656     defn.nMinKey = defn.nMaxKey = aParam[ST_KEYSIZE];
................................................................................
  1329   1329     if( strcmp(azArg[0], "-")==0 ){
  1330   1330       pInput = stdin;
  1331   1331     }else{
  1332   1332       pClose = pInput = fopen(azArg[0], "r");
  1333   1333     }
  1334   1334     zDb = azArg[1];
  1335   1335     pEnv = tdb_lsm_env();
  1336         -  rc = pEnv->xOpen(pEnv, zDb, &pOut);
         1336  +  rc = pEnv->xOpen(pEnv, zDb, 0, &pOut);
  1337   1337     if( rc!=LSM_OK ) return rc;
  1338   1338   
  1339   1339     while( feof(pInput)==0 ){
  1340   1340       char zLine[80];
  1341   1341       fgets(zLine, sizeof(zLine)-1, pInput);
  1342   1342       zLine[sizeof(zLine)-1] = '\0';
  1343   1343   
................................................................................
  1426   1426   #ifdef __linux__
  1427   1427   #include <sys/time.h>
  1428   1428   #include <sys/resource.h>
  1429   1429   
  1430   1430   static void lsmtest_rusage_report(void){
  1431   1431     int res;
  1432   1432     struct rusage r;
  1433         -  memset(&r, sizeof(r), 0);
         1433  +  memset(&r, 0, sizeof(r));
  1434   1434   
  1435   1435     res = getrusage(RUSAGE_SELF, &r);
  1436   1436     assert( res==0 );
  1437   1437   
  1438   1438     printf("# getrusage: { ru_maxrss %d ru_oublock %d ru_inblock %d }\n", 
  1439   1439         (int)r.ru_maxrss, (int)r.ru_oublock, (int)r.ru_inblock
  1440   1440     );
................................................................................
  1454   1454       {"writespeed",  do_writer_test},
  1455   1455       {"io",          st_do_io},
  1456   1456   
  1457   1457       {"insert",      do_insert},
  1458   1458       {"replay",      do_replay},
  1459   1459   
  1460   1460       {"speed",       do_speed_tests},
  1461         -    {"speed2",       do_speed_test2},
         1461  +    {"speed2",      do_speed_test2},
  1462   1462       {"show",        st_do_show},
  1463   1463       {"work",        st_do_work},
  1464   1464       {"test",        do_test},
  1465   1465       {0, 0}
  1466   1466     };
  1467   1467     int rc;                         /* Return Code */
  1468   1468     int iFunc;                      /* Index into aTest[] */

Changes to lsm-test/lsmtest_tdb3.c.

    11     11   
    12     12   #include <sys/time.h>
    13     13   
    14     14   typedef struct LsmDb LsmDb;
    15     15   typedef struct LsmWorker LsmWorker;
    16     16   typedef struct LsmFile LsmFile;
    17     17   
    18         -#define LSMTEST_DFLT_MT_MAX_CKPT (8*1024*1024)
    19         -#define LSMTEST_DFLT_MT_MIN_CKPT (2*1024*1024)
           18  +#define LSMTEST_DFLT_MT_MAX_CKPT (8*1024)
           19  +#define LSMTEST_DFLT_MT_MIN_CKPT (2*1024)
    20     20   
    21     21   #ifdef LSM_MUTEX_PTHREADS
    22     22   #include <pthread.h>
    23     23   
    24     24   #define LSMTEST_THREAD_CKPT      1
    25     25   #define LSMTEST_THREAD_WORKER    2
    26     26   #define LSMTEST_THREAD_WORKER_AC 3
................................................................................
   152    152     lsm_env *pRealEnv = tdb_lsm_env();
   153    153     return pRealEnv->xFullpath(pRealEnv, zFile, zOut, pnOut);
   154    154   }
   155    155   
   156    156   static int testEnvOpen(
   157    157     lsm_env *pEnv,                  /* Environment for current LsmDb */
   158    158     const char *zFile,              /* Name of file to open */
          159  +  int flags,
   159    160     lsm_file **ppFile               /* OUT: New file handle object */
   160    161   ){
   161    162     lsm_env *pRealEnv = tdb_lsm_env();
   162    163     LsmDb *pDb = (LsmDb *)pEnv->pVfsCtx;
   163    164     int rc;                         /* Return Code */
   164    165     LsmFile *pRet;                  /* The new file handle */
   165    166     int nFile;                      /* Length of string zFile in bytes */
   166    167   
   167    168     nFile = strlen(zFile);
   168    169     pRet = (LsmFile *)testMalloc(sizeof(LsmFile));
   169    170     pRet->pDb = pDb;
   170    171     pRet->bLog = (nFile > 4 && 0==memcmp("-log", &zFile[nFile-4], 4));
   171    172   
   172         -  rc = pRealEnv->xOpen(pRealEnv, zFile, &pRet->pReal);
          173  +  rc = pRealEnv->xOpen(pRealEnv, zFile, flags, &pRet->pReal);
   173    174     if( rc!=LSM_OK ){
   174    175       testFree(pRet);
   175    176       pRet = 0;
   176    177     }
   177    178   
   178    179     *ppFile = (lsm_file *)pRet;
   179    180     return rc;
................................................................................
   367    368     lsm_env *pRealEnv = tdb_lsm_env();
   368    369   
   369    370     if( iLock==2 && eType==LSM_LOCK_EXCL && p->pDb->bNoRecovery ){
   370    371       return LSM_BUSY;
   371    372     }
   372    373     return pRealEnv->xLock(p->pReal, iLock, eType);
   373    374   }
          375  +
          376  +static int testEnvTestLock(lsm_file *pFile, int iLock, int nLock, int eType){
          377  +  LsmFile *p = (LsmFile *)pFile;
          378  +  lsm_env *pRealEnv = tdb_lsm_env();
          379  +
          380  +  if( iLock==2 && eType==LSM_LOCK_EXCL && p->pDb->bNoRecovery ){
          381  +    return LSM_BUSY;
          382  +  }
          383  +  return pRealEnv->xTestLock(p->pReal, iLock, nLock, eType);
          384  +}
   374    385   
   375    386   static int testEnvShmMap(lsm_file *pFile, int iRegion, int sz, void **pp){
   376    387     LsmFile *p = (LsmFile *)pFile;
   377    388     lsm_env *pRealEnv = tdb_lsm_env();
   378    389     return pRealEnv->xShmMap(p->pReal, iRegion, sz, pp);
   379    390   }
   380    391   
................................................................................
   400    411     char *zFile = pDb->zName;
   401    412     char *zFree = 0;
   402    413   
   403    414     for(iFile=0; iFile<2; iFile++){
   404    415       lsm_file *pFile = 0;
   405    416       int i;
   406    417   
   407         -    pEnv->xOpen(pEnv, zFile, &pFile);
          418  +    pEnv->xOpen(pEnv, zFile, 0, &pFile);
   408    419       for(i=0; i<pDb->aFile[iFile].nSector; i++){
   409    420         u8 *aOld = pDb->aFile[iFile].aSector[i].aOld;
   410    421         if( aOld ){
   411    422           int iOpt = testPrngValue(iSeed++) % 3;
   412    423           switch( iOpt ){
   413    424             case 0:
   414    425               break;
................................................................................
   520    531     testFree((char *)pDb->pBuf);
   521    532     testFree((char *)pDb);
   522    533     return rc;
   523    534   }
   524    535   
   525    536   static int waitOnCheckpointer(LsmDb *pDb, lsm_db *db){
   526    537     int nSleep = 0;
   527         -  int nByte;
          538  +  int nKB;
   528    539     int rc;
   529    540   
   530    541     do {
   531         -    nByte = 0;
   532         -    rc = lsm_info(db, LSM_INFO_CHECKPOINT_SIZE, &nByte);
   533         -    if( rc!=LSM_OK || nByte<pDb->nMtMaxCkpt ) break;
          542  +    nKB = 0;
          543  +    rc = lsm_info(db, LSM_INFO_CHECKPOINT_SIZE, &nKB);
          544  +    if( rc!=LSM_OK || nKB<pDb->nMtMaxCkpt ) break;
   534    545       usleep(5000);
   535    546       nSleep += 5;
   536    547     }while( 1 );
   537    548   
   538    549   #if 0
   539    550       if( nSleep ) printf("# waitOnCheckpointer(): nSleep=%d\n", nSleep);
   540    551   #endif
................................................................................
   545    556   static int waitOnWorker(LsmDb *pDb){
   546    557     int rc;
   547    558     int nLimit = -1;
   548    559     int nSleep = 0;
   549    560   
   550    561     rc = lsm_config(pDb->db, LSM_CONFIG_AUTOFLUSH, &nLimit);
   551    562     do {
   552         -    int bOld, nNew, rc;
   553         -    rc = lsm_info(pDb->db, LSM_INFO_TREE_SIZE, &bOld, &nNew);
          563  +    int nOld, nNew, rc;
          564  +    rc = lsm_info(pDb->db, LSM_INFO_TREE_SIZE, &nOld, &nNew);
   554    565       if( rc!=LSM_OK ) return rc;
   555         -    if( bOld==0 || nNew<(nLimit/2) ) break;
          566  +    if( nOld==0 || nNew<(nLimit/2) ) break;
   556    567       usleep(5000);
   557    568       nSleep += 5;
   558    569     }while( 1 );
   559    570   
   560    571   #if 0
   561    572     if( nSleep ) printf("# waitOnWorker(): nSleep=%d\n", nSleep);
   562    573   #endif
................................................................................
   775    786     } aParam[] = {
   776    787       { "autoflush",        0, LSM_CONFIG_AUTOFLUSH },
   777    788       { "page_size",        0, LSM_CONFIG_PAGE_SIZE },
   778    789       { "block_size",       0, LSM_CONFIG_BLOCK_SIZE },
   779    790       { "safety",           0, LSM_CONFIG_SAFETY },
   780    791       { "autowork",         0, LSM_CONFIG_AUTOWORK },
   781    792       { "autocheckpoint",   0, LSM_CONFIG_AUTOCHECKPOINT },
   782         -    { "log_size",         0, LSM_CONFIG_LOG_SIZE },
   783    793       { "mmap",             0, LSM_CONFIG_MMAP },
   784    794       { "use_log",          0, LSM_CONFIG_USE_LOG },
   785    795       { "automerge",        0, LSM_CONFIG_AUTOMERGE },
   786    796       { "max_freelist",     0, LSM_CONFIG_MAX_FREELIST },
   787    797       { "multi_proc",       0, LSM_CONFIG_MULTIPLE_PROCESSES },
   788    798       { "worker_automerge", 1, LSM_CONFIG_AUTOMERGE },
   789    799       { "test_no_recovery", 0, TEST_NO_RECOVERY },
................................................................................
   826    836         if( rc!=0 ) return rc;
   827    837         eParam = aParam[i].eParam;
   828    838   
   829    839         z++;
   830    840         zStart = z;
   831    841         while( *z>='0' && *z<='9' ) z++;
   832    842         if( *z=='k' || *z=='K' ){
   833         -        iMul = 1024;
          843  +        iMul = 1;
   834    844           z++;
   835    845         }else if( *z=='M' || *z=='M' ){
   836         -        iMul = 1024 * 1024;
          846  +        iMul = 1024;
   837    847           z++;
   838    848         }
   839    849         nParam = z-zStart;
   840    850         if( nParam==0 || nParam>sizeof(zParam)-1 ) goto syntax_error;
   841    851         memcpy(zParam, zStart, nParam);
   842    852         zParam[nParam] = '\0';
   843    853         iVal = atoi(zParam) * iMul;
................................................................................
   851    861             case TEST_NO_RECOVERY:
   852    862               if( pLsm ) pLsm->bNoRecovery = iVal;
   853    863               break;
   854    864             case TEST_MT_MODE:
   855    865               if( pLsm ) nThread = iVal;
   856    866               break;
   857    867             case TEST_MT_MIN_CKPT:
   858         -            if( pLsm && iVal>0 ) pLsm->nMtMinCkpt = iVal;
          868  +            if( pLsm && iVal>0 ) pLsm->nMtMinCkpt = iVal*1024;
   859    869               break;
   860    870             case TEST_MT_MAX_CKPT:
   861         -            if( pLsm && iVal>0 ) pLsm->nMtMaxCkpt = iVal;
          871  +            if( pLsm && iVal>0 ) pLsm->nMtMaxCkpt = iVal*1024;
   862    872               break;
   863    873   #ifdef HAVE_ZLIB
   864    874             case TEST_COMPRESSION:
   865    875               testConfigureCompression(db);
   866    876               break;
   867    877   #endif
   868    878           }
................................................................................
   963    973   #endif
   964    974     pDb->env.xMap = testEnvMap;
   965    975     pDb->env.xUnmap = testEnvUnmap;
   966    976     pDb->env.xFileid = testEnvFileid;
   967    977     pDb->env.xClose = testEnvClose;
   968    978     pDb->env.xUnlink = testEnvUnlink;
   969    979     pDb->env.xLock = testEnvLock;
          980  +  pDb->env.xTestLock = testEnvTestLock;
   970    981     pDb->env.xShmBarrier = testEnvShmBarrier;
   971    982     pDb->env.xShmMap = testEnvShmMap;
   972    983     pDb->env.xShmUnmap = testEnvShmUnmap;
   973    984     pDb->env.xSleep = testEnvSleep;
   974    985   
   975    986     rc = lsm_new(&pDb->env, &pDb->db);
   976    987     if( rc==LSM_OK ){
................................................................................
  1003   1014   }
  1004   1015   
  1005   1016   int test_lsm_small_open(
  1006   1017     const char *zFile, 
  1007   1018     int bClear, 
  1008   1019     TestDb **ppDb
  1009   1020   ){
  1010         -  const char *zCfg = "page_size=256 block_size=65536";
         1021  +  const char *zCfg = "page_size=256 block_size=64";
  1011   1022     return testLsmOpen(zCfg, zFile, bClear, ppDb);
  1012   1023   }
  1013   1024   
  1014   1025   int test_lsm_lomem_open(
  1015   1026     const char *zFilename, 
  1016   1027     int bClear, 
  1017   1028     TestDb **ppDb
  1018   1029   ){
  1019         -    /* "max_freelist=4 autocheckpoint=32768 " */
         1030  +    /* "max_freelist=4 autocheckpoint=32" */
  1020   1031     const char *zCfg = 
  1021         -    "page_size=256 block_size=65536 autoflush=16384 "
  1022         -    "autocheckpoint=32768 "
         1032  +    "page_size=256 block_size=64 autoflush=16 "
         1033  +    "autocheckpoint=32"
  1023   1034       "mmap=0 "
  1024   1035     ;
  1025   1036     return testLsmOpen(zCfg, zFilename, bClear, ppDb);
  1026   1037   }
  1027   1038   
  1028   1039   int test_lsm_zip_open(
  1029   1040     const char *zFilename, 
  1030   1041     int bClear, 
  1031   1042     TestDb **ppDb
  1032   1043   ){
  1033   1044     const char *zCfg = 
  1034         -    "page_size=256 block_size=65536 autoflush=16384 "
  1035         -    "autocheckpoint=32768 compression=1 mmap=0 "
         1045  +    "page_size=256 block_size=64 autoflush=16 "
         1046  +    "autocheckpoint=32 compression=1 mmap=0 "
  1036   1047     ;
  1037   1048     return testLsmOpen(zCfg, zFilename, bClear, ppDb);
  1038   1049   }
  1039   1050   
  1040   1051   lsm_db *tdb_lsm(TestDb *pDb){
  1041   1052     if( pDb->pMethods->xClose==test_lsm_close ){
  1042   1053       return ((LsmDb *)pDb)->db;
................................................................................
  1147   1158       int rc = LSM_OK;
  1148   1159       int nCkpt = -1;
  1149   1160   
  1150   1161       /* Do some work. If an error occurs, exit. */
  1151   1162   
  1152   1163       pthread_mutex_unlock(&p->worker_mutex);
  1153   1164       if( p->eType==LSMTEST_THREAD_CKPT ){
  1154         -      int nByte = 0;
  1155         -      rc = lsm_info(pWorker, LSM_INFO_CHECKPOINT_SIZE, &nByte);
  1156         -      if( rc==LSM_OK && nByte>=p->pDb->nMtMinCkpt ){
         1165  +      int nKB = 0;
         1166  +      rc = lsm_info(pWorker, LSM_INFO_CHECKPOINT_SIZE, &nKB);
         1167  +      if( rc==LSM_OK && nKB>=p->pDb->nMtMinCkpt ){
  1157   1168           rc = lsm_checkpoint(pWorker, 0);
  1158   1169         }
  1159   1170       }else{
  1160   1171         int nWrite;
  1161   1172         do {
  1162   1173   
  1163   1174           if( p->eType==LSMTEST_THREAD_WORKER ){

Changes to lsm-test/lsmtest_util.c.

     1      1   
     2         -#include "lsmtest.h"
     3         -
     4      2   #include <stdarg.h>
     5      3   #include <stdio.h>
     6      4   #include <string.h>
     7      5   #include <sys/time.h>
     8         -
     9      6   
    10      7   /*
    11      8   ** Global variables used within this module.
    12      9   */
    13     10   static struct TestutilGlobal {
    14     11     char **argv;
    15     12     int argc;
    16     13   } g = {0, 0};
    17     14   
    18     15   static struct TestutilRnd {
    19         -  u32 aRand1[2048];          /* Bits 0..10 */
    20         -  u32 aRand2[2048];          /* Bits 11..21 */
    21         -  u32 aRand3[1024];          /* Bits 22..31 */
           16  +  unsigned int aRand1[2048];          /* Bits 0..10 */
           17  +  unsigned int aRand2[2048];          /* Bits 11..21 */
           18  +  unsigned int aRand3[1024];          /* Bits 22..31 */
    22     19   } r;
    23     20   
    24     21   /*************************************************************************
    25     22   ** The following block is a copy of the implementation of SQLite function
    26     23   ** sqlite3_randomness. This version has two important differences:
    27     24   **
    28     25   **   1. It always uses the same seed. So the sequence of random data output
................................................................................
    68     65       0xC4, 0xEC, 0x80, 0xD0, 0x98, 0xA7, 0x76, 0xCC, 
    69     66       0x9C, 0x2F, 0x7B, 0xFF, 0x8E, 0x0E, 0xBB, 0x90, 
    70     67       0xAE, 0x13, 0x06, 0xF5, 0x1C, 0x4E, 0x52, 0xF7
    71     68     }
    72     69   };
    73     70   
    74     71   /* Generate and return single random byte */
    75         -static u8 randomByte(void){
           72  +static unsigned char randomByte(void){
    76     73     unsigned char t;
    77     74     sqlite3Prng.i++;
    78     75     t = sqlite3Prng.s[sqlite3Prng.i];
    79     76     sqlite3Prng.j += t;
    80     77     sqlite3Prng.s[sqlite3Prng.i] = sqlite3Prng.s[sqlite3Prng.j];
    81     78     sqlite3Prng.s[sqlite3Prng.j] = t;
    82     79     t += sqlite3Prng.s[sqlite3Prng.i];
................................................................................
    94     91   }
    95     92   /*
    96     93   ** End of code copied from SQLite.
    97     94   *************************************************************************/
    98     95   
    99     96   
   100     97   int testPrngInit(void){
   101         -  sqlite3_initialize();
   102     98     randomBlob(sizeof(r.aRand1), (unsigned char *)r.aRand1);
   103     99     randomBlob(sizeof(r.aRand2), (unsigned char *)r.aRand2);
   104    100     randomBlob(sizeof(r.aRand3), (unsigned char *)r.aRand3);
   105         -  return LSM_OK;
          101  +  return 0;
   106    102   }
   107    103   
   108         -u32 testPrngValue(u32 iVal){
          104  +unsigned int testPrngValue(unsigned int iVal){
   109    105     return
   110    106       r.aRand1[iVal & 0x000007FF] ^
   111    107       r.aRand2[(iVal>>11) & 0x000007FF] ^
   112    108       r.aRand3[(iVal>>22) & 0x000003FF]
   113    109     ;
   114    110   }
   115    111   
   116         -void testPrngArray(u32 iVal, u32 *aOut, int nOut){
          112  +void testPrngArray(unsigned int iVal, unsigned int *aOut, int nOut){
   117    113     int i;
   118    114     for(i=0; i<nOut; i++){
   119    115       aOut[i] = testPrngValue(iVal+i);
   120    116     }
   121    117   }
   122    118   
   123         -void testPrngString(u32 iVal, char *aOut, int nOut){
          119  +void testPrngString(unsigned int iVal, char *aOut, int nOut){
   124    120     int i;
   125    121     for(i=0; i<(nOut-1); i++){
   126    122       aOut[i] = 'a' + (testPrngValue(iVal+i) % 26);
   127    123     }
   128    124     aOut[i] = '\0';
   129    125   }
   130    126   
................................................................................
   148    144     struct Entry { const char *zName; };
   149    145     struct Entry *pEntry;
   150    146     const char *zPrev = 0;
   151    147   
   152    148     testPrintError("unrecognized %s \"%s\": must be ", zType, zArg);
   153    149     for(pEntry=(struct Entry *)aData; 
   154    150         pEntry->zName; 
   155         -      pEntry=(struct Entry *)&((u8 *)pEntry)[sz]
          151  +      pEntry=(struct Entry *)&((unsigned char *)pEntry)[sz]
   156    152     ){
   157    153       if( zPrev ){ testPrintError("%s, ", zPrev); }
   158    154       zPrev = pEntry->zName;
   159    155     }
   160    156     testPrintError("or %s\n", zPrev);
   161    157   }
   162    158   
................................................................................
   173    169   
   174    170     int i = 0;
   175    171     int iOut = -1;
   176    172     int nOut = 0;
   177    173   
   178    174     for(pEntry=(struct Entry *)aData; 
   179    175         pEntry->zName; 
   180         -      pEntry=(struct Entry *)&((u8 *)pEntry)[sz]
          176  +      pEntry=(struct Entry *)&((unsigned char *)pEntry)[sz]
   181    177     ){
   182    178       int nName = strlen(pEntry->zName);
   183    179       if( nArg<=nName && memcmp(pEntry->zName, zArg, nArg)==0 ){
   184    180         iOut = i;
   185    181         if( nName==nArg ){
   186    182           nOut = 1;
   187    183           break;

Added lsm-test/sqltest.c.

            1  +/*
            2  +** 2013 March 1
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +** This file contains C code for a program that links against SQLite
           13  +** versions 3 and 4. It contains a few simple performance test routines
           14  +** that can be run against either database system.
           15  +*/
           16  +
           17  +#include "sqlite4.h"
           18  +#include "sqlite3.h"
           19  +#include "lsm.h"
           20  +
           21  +#include <stdio.h>
           22  +#include <stdlib.h>
           23  +#include <assert.h>
           24  +#include <unistd.h>
           25  +
           26  +#define SQLITE3_DB_FILE "test.db3"
           27  +#define SQLITE4_DB_FILE "test.db4"
           28  +
           29  +#include "lsmtest_util.c"
           30  +
           31  +/*
           32  +** Unlink database zDb and its supporting files (wal, shm, journal, and log).
           33  +** This function works with both lsm and sqlite3 databases.
           34  +*/
           35  +static int unlink_db(const char *zDb){
           36  +  int i;
           37  +  const char *azExt[] = { "", "-shm", "-wal", "-journal", "-log", 0 };
           38  +
           39  +  for(i=0; azExt[i]; i++){
           40  +    char *zFile = sqlite4_mprintf(0, "%s%s", zDb, azExt[i]);
           41  +    unlink(zFile);
           42  +    sqlite4_free(0, zFile);
           43  +  }
           44  +
           45  +  return 0;
           46  +}
           47  +
           48  +static char *create_schema_sql(int nIdx){
           49  +  char *zSchema;
           50  +  int i;
           51  +
           52  +  zSchema = sqlite4_mprintf(0, "CREATE TABLE t1(k PRIMARY KEY,");
           53  +  for(i=0; i<nIdx; i++){
           54  +    zSchema = sqlite4_mprintf(0, "%z c%d BLOB,", zSchema, i);
           55  +  }
           56  +  zSchema = sqlite4_mprintf(0, "%z v BLOB);", zSchema);
           57  +
           58  +  for(i=0; i<nIdx; i++){
           59  +    zSchema = sqlite4_mprintf(
           60  +      0, "%z\nCREATE INDEX i%d ON t1 (c%d);", zSchema, i, i
           61  +    );
           62  +  }
           63  +
           64  +  return zSchema;
           65  +}
           66  +
           67  +static char *create_insert_sql(int nIdx){
           68  +  char *zInsert;
           69  +  int i;
           70  +
           71  +  zInsert = sqlite4_mprintf(0, "INSERT INTO t1 VALUES(rblob(:1, 8, 20),");
           72  +  for(i=0; i<nIdx; i++){
           73  +    zInsert = sqlite4_mprintf(0, "%z rblob((:1<<%d)+:1, 8, 20),", zInsert, i);
           74  +  }
           75  +  zInsert = sqlite4_mprintf(0, "%z rblob((:1<<%d)+:1, 100, 150));", zInsert, i);
           76  +
           77  +  return zInsert;
           78  +}
           79  +
           80  +static char *create_select_sql(int iIdx){
           81  +  char *zSql;
           82  +  if( iIdx==0 ){
           83  +    zSql = sqlite4_mprintf(0, "SELECT * FROM t1 WHERE k = rblob(:1, 8, 20)");
           84  +  }else{
           85  +    int iCol = iIdx-1;
           86  +    zSql = sqlite4_mprintf(0, 
           87  +        "SELECT * FROM t1 WHERE c%d = rblob((:1<<%d)+:1, 8, 20)", iCol, iCol
           88  +    );
           89  +  }
           90  +  return zSql;
           91  +}
           92  +
           93  +static int do_explode(const char *zLine, int rc, int iLine){
           94  +  if( rc ){
           95  +    fprintf(stderr, "ERROR: \"%s\" at line %d failed. rc=%d\n", 
           96  +        zLine, iLine, rc
           97  +    );
           98  +    exit(-1);
           99  +  }
          100  +  return 0;
          101  +}
          102  +#define EXPLODE(rc) do_explode(#rc, rc, __LINE__)
          103  +
          104  +
          105  +/*************************************************************************
          106  +** Implementations of the rblob(nMin, nMax) function. One for src4 and
          107  +** one for sqlite3.
          108  +*/
          109  +
          110  +/* src4 implementation */
          111  +static void rblobFunc4(sqlite4_context *ctx, int nArg, sqlite4_value **apArg){
          112  +  unsigned char aBlob[1000];
          113  +
          114  +  int iSeed = sqlite4_value_int(apArg[0]);
          115  +  int nMin = sqlite4_value_int(apArg[1]);
          116  +  int nMax = sqlite4_value_int(apArg[2]);
          117  +  int nByte;
          118  +
          119  +  nByte = testPrngValue(iSeed + 1000000) & 0x7FFFFFFF;
          120  +  nByte = (nByte % (nMax+1-nMin)) + nMin;
          121  +  assert( nByte>=nMin && nByte<=nMax );
          122  +  if( nByte>sizeof(aBlob) ) nByte = sizeof(aBlob);
          123  +  testPrngArray(iSeed, (unsigned int *)aBlob, (nByte+3)/4);
          124  +
          125  +  sqlite4_result_blob(ctx, aBlob, nByte, SQLITE4_TRANSIENT, 0);
          126  +}
          127  +static void install_rblob_function4(sqlite4 *db){
          128  +  testPrngInit();
          129  +  sqlite4_create_function(db, "rblob", 3, SQLITE4_UTF8, 0, rblobFunc4, 0, 0);
          130  +}
          131  +
          132  +/* sqlite3 implementation */
          133  +static void rblobFunc3(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
          134  +  unsigned char aBlob[1000];
          135  +
          136  +  int iSeed = sqlite3_value_int(apArg[0]);
          137  +  int nMin = sqlite3_value_int(apArg[1]);
          138  +  int nMax = sqlite3_value_int(apArg[2]);
          139  +  int nByte;
          140  +
          141  +  nByte = testPrngValue(iSeed + 1000000) & 0x7FFFFFFF;
          142  +  nByte = (nByte % (nMax+1-nMin)) + nMin;
          143  +  assert( nByte>=nMin && nByte<=nMax );
          144  +  if( nByte>sizeof(aBlob) ) nByte = sizeof(aBlob);
          145  +  testPrngArray(iSeed, (unsigned int *)aBlob, (nByte+3)/4);
          146  +
          147  +  sqlite3_result_blob(ctx, aBlob, nByte, SQLITE_TRANSIENT);
          148  +}
          149  +static void install_rblob_function3(sqlite3 *db){
          150  +  testPrngInit();
          151  +  sqlite3_create_function(db, "rblob", 3, SQLITE_UTF8, 0, rblobFunc3, 0, 0);
          152  +}
          153  +/*
          154  +** End of rblob() implementations.
          155  +*************************************************************************/
          156  +
          157  +/*************************************************************************
          158  +** Integer query functions for sqlite3 and src4.
          159  +*/
          160  +static int integer_query4(sqlite4 *db, const char *zSql){
          161  +  int iRet;
          162  +  sqlite4_stmt *pStmt;
          163  +
          164  +  EXPLODE( sqlite4_prepare(db, zSql, -1, &pStmt, 0) );
          165  +  EXPLODE( SQLITE_ROW!=sqlite4_step(pStmt) );
          166  +  iRet = sqlite4_column_int(pStmt, 0);
          167  +  EXPLODE( sqlite4_finalize(pStmt) );
          168  +
          169  +  return iRet;
          170  +}
          171  +static int integer_query3(sqlite3 *db, const char *zSql){
          172  +  int iRet;
          173  +  sqlite3_stmt *pStmt;
          174  +
          175  +  EXPLODE( sqlite3_prepare(db, zSql, -1, &pStmt, 0) );
          176  +  EXPLODE( SQLITE_ROW!=sqlite3_step(pStmt) );
          177  +  iRet = sqlite3_column_int(pStmt, 0);
          178  +  EXPLODE( sqlite3_finalize(pStmt) );
          179  +
          180  +  return iRet;
          181  +}
          182  +/*
          183  +** End of integer query implementations.
          184  +*************************************************************************/
          185  +
          186  +static int do_insert1_test4(
          187  +  int nRow,                       /* Number of rows to insert in total */
          188  +  int nRowPerTrans,               /* Number of rows per transaction */
          189  +  int nIdx,                       /* Number of aux indexes (aside from PK) */
          190  +  int iSync                       /* PRAGMA synchronous value (0, 1 or 2) */
          191  +){
          192  +  char *zCreateTbl;               /* Create table statement */
          193  +  char *zInsert;                  /* INSERT statement */
          194  +  sqlite4_stmt *pInsert;          /* Compiled INSERT statement */
          195  +  sqlite4 *db = 0;                /* Database handle */
          196  +  int i;                          /* Counter to count nRow rows */
          197  +  int nMs;                        /* Test time in ms */
          198  +
          199  +  lsm_db *pLsm;
          200  +
          201  +  unlink_db(SQLITE4_DB_FILE);
          202  +  EXPLODE(  sqlite4_open(0, SQLITE4_DB_FILE, &db)  );
          203  +  sqlite4_kvstore_control(db, "main", SQLITE4_KVCTRL_LSM_HANDLE, &pLsm);
          204  +  i = iSync;
          205  +  lsm_config(pLsm, LSM_CONFIG_SAFETY, &i);
          206  +  assert( i==iSync );
          207  +
          208  +  install_rblob_function4(db);
          209  +
          210  +  zCreateTbl = create_schema_sql(nIdx);
          211  +  zInsert = create_insert_sql(nIdx);
          212  +
          213  +  /* Create the db schema and prepare the INSERT statement */
          214  +  EXPLODE(  sqlite4_exec(db, zCreateTbl, 0, 0, 0)  );
          215  +  EXPLODE(  sqlite4_prepare(db, zInsert, -1, &pInsert, 0)  );
          216  +
          217  +  /* Run the test */
          218  +  testTimeInit();
          219  +  for(i=0; i<nRow; i++){
          220  +    if( (i % nRowPerTrans)==0 ){
          221  +      if( i!=0 ) EXPLODE(  sqlite4_exec(db, "COMMIT", 0, 0, 0)  );
          222  +      EXPLODE(  sqlite4_exec(db, "BEGIN", 0, 0, 0)  );
          223  +    }
          224  +    sqlite4_bind_int(pInsert, 1, i);
          225  +    sqlite4_step(pInsert);
          226  +    EXPLODE(  sqlite4_reset(pInsert)  );
          227  +  }
          228  +  EXPLODE(  sqlite4_exec(db, "COMMIT", 0, 0, 0)  );
          229  +
          230  +  /* Free all the stuff allocated above */
          231  +  sqlite4_finalize(pInsert);
          232  +  sqlite4_free(0, zCreateTbl);
          233  +  sqlite4_free(0, zInsert);
          234  +  sqlite4_close(db);
          235  +  nMs = testTimeGet();
          236  +
          237  +  /* Print out the time taken by the test */
          238  +  printf("%.3f seconds\n", (double)nMs / 1000.0);
          239  +  return 0;
          240  +}
          241  +static int do_insert1_test3(
          242  +  int nRow,                       /* Number of rows to insert in total */
          243  +  int nRowPerTrans,               /* Number of rows per transaction */
          244  +  int nIdx,                       /* Number of aux indexes (aside from PK) */
          245  +  int iSync                       /* PRAGMA synchronous value (0, 1 or 2) */
          246  +){
          247  +  char *zCreateTbl;               /* Create table statement */
          248  +  char *zInsert;                  /* INSERT statement */
          249  +  char *zSync;                    /* "PRAGMA synchronous=" statement */
          250  +  sqlite3_stmt *pInsert;          /* Compiled INSERT statement */
          251  +  sqlite3 *db = 0;                /* Database handle */
          252  +  int i;                          /* Counter to count nRow rows */
          253  +  int nMs;                        /* Test time in ms */
          254  +
          255  +  unlink_db(SQLITE3_DB_FILE);
          256  +  EXPLODE( sqlite3_open(SQLITE3_DB_FILE, &db) );
          257  +  EXPLODE( sqlite3_exec(db, "PRAGMA journal_mode=WAL", 0, 0, 0) );
          258  +  zSync = sqlite4_mprintf(0, "PRAGMA synchronous=%d", iSync);
          259  +  EXPLODE( sqlite3_exec(db, zSync, 0, 0, 0) );
          260  +  sqlite4_free(0, zSync);
          261  +
          262  +  install_rblob_function3(db);
          263  +
          264  +  zCreateTbl = create_schema_sql(nIdx);
          265  +  zInsert = create_insert_sql(nIdx);
          266  +
          267  +  /* Create the db schema and prepare the INSERT statement */
          268  +  EXPLODE(  sqlite3_exec(db, zCreateTbl, 0, 0, 0)  );
          269  +  EXPLODE(  sqlite3_prepare(db, zInsert, -1, &pInsert, 0)  );
          270  +
          271  +  /* Run the test */
          272  +  testTimeInit();
          273  +  for(i=0; i<nRow; i++){
          274  +    if( (i % nRowPerTrans)==0 ){
          275  +      if( i!=0 ) EXPLODE(  sqlite3_exec(db, "COMMIT", 0, 0, 0)  );
          276  +      EXPLODE(  sqlite3_exec(db, "BEGIN", 0, 0, 0)  );
          277  +    }
          278  +    sqlite3_bind_int(pInsert, 1, i);
          279  +    sqlite3_step(pInsert);
          280  +    EXPLODE(  sqlite3_reset(pInsert)  );
          281  +  }
          282  +  EXPLODE(  sqlite3_exec(db, "COMMIT", 0, 0, 0)  );
          283  +
          284  +  /* Finalize the statement and close the db. */
          285  +  sqlite3_finalize(pInsert);
          286  +  sqlite3_close(db);
          287  +  nMs = testTimeGet();
          288  +
          289  +  /* Free the stuff allocated above */
          290  +  sqlite4_free(0, zCreateTbl);
          291  +  sqlite4_free(0, zInsert);
          292  +
          293  +  /* Print out the time taken by the test */
          294  +  printf("%.3f seconds\n", (double)nMs / 1000.0);
          295  +  return 0;
          296  +}
          297  +
          298  +static int do_insert1(int argc, char **argv){
          299  +  struct Insert1Arg {
          300  +    const char *zArg;
          301  +    int nMin;
          302  +    int nMax;
          303  +  } aArg[] = { 
          304  +    {"-db",           3,    4}, 
          305  +    {"-rows",         1,    10000000}, 
          306  +    {"-rowspertrans", 1,    10000000}, 
          307  +    {"-indexes",      0,    20}, 
          308  +    {"-sync",         0,    2}, 
          309  +    {0,0,0}
          310  +  };
          311  +  int i;
          312  +
          313  +  int iDb = 4;                    /* SQLite 3 or 4 */
          314  +  int nRow = 50000;               /* Total rows: 50000 */
          315  +  int nRowPerTrans = 10;          /* Total rows each transaction: 50000 */
          316  +  int nIdx = 3;                   /* Number of auxilliary indexes */
          317  +  int iSync = 1;                  /* PRAGMA synchronous setting */
          318  +
          319  +  for(i=0; i<argc; i++){
          320  +    int iSel;
          321  +    int iVal;
          322  +    int rc;
          323  +
          324  +    rc = testArgSelectX(aArg, "argument", sizeof(aArg[0]), argv[i], &iSel);
          325  +    if( rc!=0 ) return -1;
          326  +    if( i==argc-1 ){
          327  +      fprintf(stderr, "option %s requires an argument\n", aArg[iSel].zArg);
          328  +      return -1;
          329  +    }
          330  +    iVal = atoi(argv[++i]);
          331  +    if( iVal<aArg[iSel].nMin || iVal>aArg[iSel].nMax ){
          332  +      fprintf(stderr, "option %s out of range (%d..%d)\n", 
          333  +          aArg[iSel].zArg, aArg[iSel].nMin, aArg[iSel].nMax 
          334  +      );
          335  +      return -1;
          336  +    }
          337  +
          338  +    switch( iSel ){
          339  +      case 0: iDb = iVal;          break;
          340  +      case 1: nRow = iVal;         break;
          341  +      case 2: nRowPerTrans = iVal; break;
          342  +      case 3: nIdx = iVal;         break;
          343  +      case 4: iSync = iVal;        break;
          344  +    }
          345  +  }
          346  +
          347  +  printf("insert1: db=%d rows=%d rowspertrans=%d indexes=%d sync=%d ... ", 
          348  +      iDb, nRow, nRowPerTrans, nIdx, iSync
          349  +  );
          350  +  fflush(stdout);
          351  +  if( iDb==3 ){
          352  +    do_insert1_test3(nRow, nRowPerTrans, nIdx, iSync);
          353  +  }else{
          354  +    do_insert1_test4(nRow, nRowPerTrans, nIdx, iSync);
          355  +  }
          356  +
          357  +  return 0;
          358  +}
          359  +
          360  +static int do_select1_test4(
          361  +  int nRow,                       /* Number of rows to read in total */
          362  +  int nRowPerTrans,               /* Number of rows per transaction */
          363  +  int iIdx
          364  +){
          365  +  int nMs = 0;
          366  +  sqlite4_stmt *pSelect = 0;
          367  +  char *zSelect;
          368  +  sqlite4 *db;
          369  +  int i;
          370  +  int nTblRow;
          371  +
          372  +  EXPLODE( sqlite4_open(0, SQLITE4_DB_FILE, &db) );
          373  +  install_rblob_function4(db);
          374  +
          375  +  nTblRow = integer_query4(db, "SELECT count(*) FROM t1");
          376  +
          377  +  /* Create the db schema and prepare the INSERT statement */
          378  +  zSelect = create_select_sql(iIdx);
          379  +  EXPLODE(  sqlite4_prepare(db, zSelect, -1, &pSelect, 0)  );
          380  +
          381  +  testTimeInit();
          382  +  for(i=0; i<nRow; i++){
          383  +    if( (i % nRowPerTrans)==0 ){
          384  +      if( i!=0 ) EXPLODE(  sqlite4_exec(db, "COMMIT", 0, 0, 0)  );
          385  +      EXPLODE(  sqlite4_exec(db, "BEGIN", 0, 0, 0)  );
          386  +    }
          387  +    sqlite4_bind_int(pSelect, 1, (i*211)%nTblRow);
          388  +    EXPLODE(  SQLITE_ROW!=sqlite4_step(pSelect)  );
          389  +    EXPLODE(  sqlite4_reset(pSelect)  );
          390  +  }
          391  +  EXPLODE(  sqlite4_exec(db, "COMMIT", 0, 0, 0)  );
          392  +  nMs = testTimeGet();
          393  +
          394  +  sqlite4_finalize(pSelect);
          395  +  sqlite4_close(db);
          396  +  sqlite4_free(0, zSelect);
          397  +
          398  +  printf("%.3f seconds\n", (double)nMs / 1000.0);
          399  +  return 0;
          400  +}
          401  +static int do_select1_test3(
          402  +  int nRow,                       /* Number of rows to read in total */
          403  +  int nRowPerTrans,               /* Number of rows per transaction */
          404  +  int iIdx
          405  +){
          406  +  int nMs = 0;
          407  +  sqlite3_stmt *pSelect = 0;
          408  +  char *zSelect;
          409  +  sqlite3 *db;
          410  +  int i;
          411  +  int nTblRow;
          412  +
          413  +  EXPLODE( sqlite3_open(SQLITE3_DB_FILE, &db) );
          414  +  install_rblob_function3(db);
          415  +
          416  +  nTblRow = integer_query3(db, "SELECT count(*) FROM t1");
          417  +
          418  +  /* Create the db schema and prepare the INSERT statement */
          419  +  zSelect = create_select_sql(iIdx);
          420  +  EXPLODE(  sqlite3_prepare(db, zSelect, -1, &pSelect, 0)  );
          421  +
          422  +  testTimeInit();
          423  +  for(i=0; i<nRow; i++){
          424  +    if( (i % nRowPerTrans)==0 ){
          425  +      if( i!=0 ) EXPLODE(  sqlite3_exec(db, "COMMIT", 0, 0, 0)  );
          426  +      EXPLODE(  sqlite3_exec(db, "BEGIN", 0, 0, 0)  );
          427  +    }
          428  +    sqlite3_bind_int(pSelect, 1, (i*211)%nTblRow);
          429  +    EXPLODE(  SQLITE_ROW!=sqlite3_step(pSelect)  );
          430  +    EXPLODE(  sqlite3_reset(pSelect)  );
          431  +  }
          432  +  EXPLODE(  sqlite3_exec(db, "COMMIT", 0, 0, 0)  );
          433  +  nMs = testTimeGet();
          434  +
          435  +  sqlite3_finalize(pSelect);
          436  +  sqlite3_close(db);
          437  +  sqlite4_free(0, zSelect);
          438  +
          439  +  printf("%.3f seconds\n", (double)nMs / 1000.0);
          440  +  return 0;
          441  +}
          442  +
          443  +static int do_select1(int argc, char **argv){
          444  +  struct Insert1Arg {
          445  +    const char *zArg;
          446  +    int nMin;
          447  +    int nMax;
          448  +  } aArg[] = {
          449  +    {"-db",           3,    4}, 
          450  +    {"-rows",         1,    10000000}, 
          451  +    {"-rowspertrans", 1,    10000000}, 
          452  +    {"-index",        0,    21}, 
          453  +    {0,0,0}
          454  +  };
          455  +  int i;
          456  +
          457  +  int iDb = 4;                    /* SQLite 3 or 4 */
          458  +  int nRow = 50000;               /* Total rows: 50000 */
          459  +  int nRowPerTrans = 10;          /* Total rows each transaction: 50000 */
          460  +  int iIdx = 0;
          461  +
          462  +  for(i=0; i<argc; i++){
          463  +    int iSel;
          464  +    int iVal;
          465  +    int rc;
          466  +
          467  +    rc = testArgSelectX(aArg, "argument", sizeof(aArg[0]), argv[i], &iSel);
          468  +    if( rc!=0 ) return -1;
          469  +    if( i==argc-1 ){
          470  +      fprintf(stderr, "option %s requires an argument\n", aArg[iSel].zArg);
          471  +      return -1;
          472  +    }
          473  +    iVal = atoi(argv[++i]);
          474  +    if( iVal<aArg[iSel].nMin || iVal>aArg[iSel].nMax ){
          475  +      fprintf(stderr, "option %s out of range (%d..%d)\n", 
          476  +          aArg[iSel].zArg, aArg[iSel].nMin, aArg[iSel].nMax 
          477  +      );
          478  +      return -1;
          479  +    }
          480  +
          481  +    switch( iSel ){
          482  +      case 0: iDb = iVal;          break;
          483  +      case 1: nRow = iVal;         break;
          484  +      case 2: nRowPerTrans = iVal; break;
          485  +      case 3: iIdx = iVal;         break;
          486  +    }
          487  +  }
          488  +
          489  +  printf("select1: db=%d rows=%d rowspertrans=%d index=%d ... ", 
          490  +      iDb, nRow, nRowPerTrans, iIdx
          491  +  );
          492  +  fflush(stdout);
          493  +  if( iDb==3 ){
          494  +    do_select1_test3(nRow, nRowPerTrans, iIdx);
          495  +  }else{
          496  +    do_select1_test4(nRow, nRowPerTrans, iIdx);
          497  +  }
          498  +
          499  +  return 0;
          500  +}
          501  +
          502  +int main(int argc, char **argv){
          503  +  struct SqltestArg {
          504  +    const char *zPrg;
          505  +    int (*xPrg)(int, char **);
          506  +  } aArg[] = { 
          507  +    {"select", do_select1},
          508  +    {"insert", do_insert1},
          509  +    {0, 0}
          510  +  };
          511  +  int iSel;
          512  +  int rc;
          513  +
          514  +  if( argc<2 ){
          515  +    fprintf(stderr, "Usage: %s sub-program...\n", argv[0]);
          516  +    return -1;
          517  +  }
          518  +
          519  +  rc = testArgSelectX(aArg, "sub-program", sizeof(aArg[0]), argv[1], &iSel);
          520  +  if( rc!=0 ) return -1;
          521  +
          522  +  aArg[iSel].xPrg(argc-2, argv+2);
          523  +  return 0;
          524  +}

Changes to main.mk.

    40     40   # Once the macros above are defined, the rest of this make script will
    41     41   # build the SQLite library and testing tools.
    42     42   ################################################################################
    43     43   
    44     44   # FIXME:  Required options for now.
    45     45   #
    46     46   OPTS += -DLSM_MUTEX_NONE
    47         -OPTS += -DSQLITE4_DEBUG=1 -DLSM_DEBUG=1
           47  +#OPTS += -DSQLITE4_DEBUG=1 -DLSM_DEBUG=1
    48     48   OPTS += -DHAVE_GMTIME_R
    49     49   OPTS += -DHAVE_LOCALTIME_R
    50     50   OPTS += -DHAVE_MALLOC_USABLE_SIZE
    51     51   OPTS += -DHAVE_USLEEP
    52         -OPTS += -DSQLITE4_MEMDEBUG=1
           52  +#OPTS += -DSQLITE4_MEMDEBUG=1
    53     53   #OPTS += -DSQLITE4_NO_SYNC=1 -DLSM_NO_SYNC=1
    54     54   OPTS += -DSQLITE4_OMIT_ANALYZE
    55     55   OPTS += -DSQLITE4_OMIT_AUTOMATIC_INDEX
    56     56   OPTS += -DSQLITE4_OMIT_BTREECOUNT
    57     57   OPTS += -DSQLITE4_OMIT_VIRTUALTABLE=1
    58     58   OPTS += -DSQLITE4_OMIT_XFER_OPT
    59     59   OPTS += -DSQLITE4_THREADSAFE=0
................................................................................
    66     66   
    67     67   TCPPX = g++ -Wall -g -I. -I$(TOP)/src $(OPTS)
    68     68   
    69     69   
    70     70   LIBOBJ+= vdbe.o parse.o \
    71     71            alter.o analyze.o attach.o auth.o \
    72     72            build.o \
    73         -         callback.o complete.o ctime.o date.o delete.o expr.o fault.o fkey.o \
    74         -	 fts5.o fts5func.o \
           73  +         callback.o complete.o ctime.o date.o delete.o env.o expr.o \
           74  +         fault.o fkey.o fts5.o fts5func.o \
    75     75            func.o global.o hash.o \
    76     76            icu.o insert.o kv.o kvlsm.o kvmem.o legacy.o \
    77     77            lsm_ckpt.o lsm_file.o lsm_log.o lsm_main.o lsm_mem.o lsm_mutex.o \
    78     78            lsm_shared.o lsm_str.o lsm_sorted.o lsm_tree.o \
    79     79            lsm_unix.o lsm_varint.o \
    80         -         main.o malloc.o math.o mem0.o mem1.o mem2.o mem3.o mem5.o \
           80  +         main.o malloc.o math.o mem.o mem0.o mem1.o mem2.o mem3.o mem5.o \
    81     81            mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
    82     82            opcodes.o os.o \
    83     83            pragma.o prepare.o printf.o \
    84     84            random.o resolve.o rowset.o rtree.o select.o status.o \
    85     85            tokenize.o trigger.o \
    86     86            update.o util.o varint.o \
    87     87            vdbeapi.o vdbeaux.o vdbecodec.o vdbecursor.o \
................................................................................
    97     97     $(TOP)/src/auth.c \
    98     98     $(TOP)/src/build.c \
    99     99     $(TOP)/src/callback.c \
   100    100     $(TOP)/src/complete.c \
   101    101     $(TOP)/src/ctime.c \
   102    102     $(TOP)/src/date.c \
   103    103     $(TOP)/src/delete.c \
          104  +  $(TOP)/src/env.c \
   104    105     $(TOP)/src/expr.c \
   105    106     $(TOP)/src/fault.c \
   106    107     $(TOP)/src/fkey.c \
   107    108     $(TOP)/src/fts5.c \
   108    109     $(TOP)/src/fts5func.c \
   109    110     $(TOP)/src/func.c \
   110    111     $(TOP)/src/global.c \
................................................................................
   130    131     $(TOP)/src/lsm_sorted.c \
   131    132     $(TOP)/src/lsm_tree.c \
   132    133     $(TOP)/src/lsm_unix.c \
   133    134     $(TOP)/src/lsm_varint.c \
   134    135     $(TOP)/src/main.c \
   135    136     $(TOP)/src/malloc.c \
   136    137     $(TOP)/src/math.c \
          138  +  $(TOP)/src/mem.c \
   137    139     $(TOP)/src/mem0.c \
   138    140     $(TOP)/src/mem1.c \
   139    141     $(TOP)/src/mem2.c \
   140    142     $(TOP)/src/mem3.c \
   141    143     $(TOP)/src/mem5.c \
   142    144     $(TOP)/src/mutex.c \
   143    145     $(TOP)/src/mutex.h \
................................................................................
   485    487   TESTFIXTURE_PREREQ  = $(TESTSRC) $(TESTSRC2) 
   486    488   TESTFIXTURE_PREREQ += $(TOP)/src/tclsqlite.c
   487    489   TESTFIXTURE_PREREQ += libsqlite4.a
   488    490   
   489    491   testfixture$(EXE): $(TESTFIXTURE_PREREQ)
   490    492   	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
   491    493   		$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c                \
   492         -		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB) libsqlite4.a
          494  +		-o testfixture$(EXE) $(LIBTCL) libsqlite4.a $(THREADLIB)
   493    495   
   494    496   amalgamation-testfixture$(EXE): sqlite4.c $(TESTSRC) $(TOP)/src/tclsqlite.c
   495    497   	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
   496    498   		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite4.c                  \
   497    499   		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
   498    500   
   499    501   fts3-testfixture$(EXE): sqlite4.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
................................................................................
   527    529   # 
   528    530   threadtest3$(EXE): sqlite4.o $(TOP)/test/threadtest3.c $(TOP)/test/tt3_checkpoint.c
   529    531   	$(TCCX) -O2 sqlite4.o $(TOP)/test/threadtest3.c \
   530    532   		-o threadtest3$(EXE) $(THREADLIB)
   531    533   
   532    534   threadtest: threadtest3$(EXE)
   533    535   	./threadtest3$(EXE)
          536  +
          537  +SQLSRC = $(TOP)/lsm-test/sqltest.c $(TOP)/lsm-test/lsmtest_util.c 
          538  +sqltest$(EXE): $(SQLSRC) libsqlite4.a
          539  +	$(TCCX) $(TOP)/lsm-test/sqltest.c \
          540  +        -o sqltest$(EXE) -lsqlite3 libsqlite4.a $(THREADLIB)
   534    541   
   535    542   TEST_EXTENSION = $(SHPREFIX)testloadext.$(SO)
   536    543   $(TEST_EXTENSION): $(TOP)/test/test_loadext.c
   537    544   	$(MKSHLIB) $(TOP)/test/test_loadext.c -o $(TEST_EXTENSION)
   538    545   
   539    546   extensiontest: testfixture$(EXE) $(TEST_EXTENSION)
   540    547   	./testfixture$(EXE) $(TOP)/test/loadext.test

Changes to src/alter.c.

    75     75           len = sqlite4GetToken(zCsr, &token);
    76     76         } while( token==TK_SPACE );
    77     77         assert( len>0 );
    78     78       } while( token!=TK_LP && token!=TK_USING );
    79     79   
    80     80       zRet = sqlite4MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, 
    81     81          zTableName, tname.z+tname.n);
    82         -    sqlite4_result_text(context, zRet, -1, SQLITE4_TRANSIENT);
           82  +    sqlite4_result_text(context, zRet, -1, SQLITE4_TRANSIENT, 0);
    83     83       sqlite4DbFree(db, zRet);
    84     84     }
    85     85   }
    86     86   
    87     87   /*
    88     88   ** This C function implements an SQL user function that is used by SQL code
    89     89   ** generated by the ALTER TABLE ... RENAME command to modify the definition
................................................................................
   138    138           zInput = &z[n];
   139    139         }
   140    140         sqlite4DbFree(db, zParent);
   141    141       }
   142    142     }
   143    143   
   144    144     zResult = sqlite4MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), 
   145         -  sqlite4_result_text(context, zResult, -1, SQLITE4_TRANSIENT);
          145  +  sqlite4_result_text(context, zResult, -1, SQLITE4_TRANSIENT, 0);
   146    146     sqlite4DbFree(db, zOutput);
   147    147     sqlite4DbFree(db, zResult);
   148    148   }
   149    149   #endif
   150    150   
   151    151   #ifndef SQLITE4_OMIT_TRIGGER
   152    152   /* This function is used by SQL generated to implement the
................................................................................
   216    216       } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) );
   217    217   
   218    218       /* Variable tname now contains the token that is the old table-name
   219    219       ** in the CREATE TRIGGER statement.
   220    220       */
   221    221       zRet = sqlite4MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, 
   222    222          zTableName, tname.z+tname.n);
   223         -    sqlite4_result_text(context, zRet, -1, SQLITE4_TRANSIENT);
          223  +    sqlite4_result_text(context, zRet, -1, SQLITE4_TRANSIENT, 0);
   224    224       sqlite4DbFree(db, zRet);
   225    225     }
   226    226   }
   227    227   #endif   /* !SQLITE4_OMIT_TRIGGER */
   228    228   
   229    229   /*
   230    230   ** Register built-in functions used to help implement ALTER TABLE

Changes to src/attach.c.

   239    239     if( pDb->pKV->iTransLevel ){
   240    240       sqlite4_snprintf(zErr,sizeof(zErr), "database %s is locked", zName);
   241    241       goto detach_error;
   242    242     }
   243    243   
   244    244     sqlite4KVStoreClose(pDb->pKV);
   245    245     pDb->pKV = 0;
          246  +  sqlite4SchemaClear(db->pEnv, pDb->pSchema);
          247  +  sqlite4DbFree(db, pDb->pSchema);
   246    248     pDb->pSchema = 0;
   247    249     sqlite4ResetInternalSchema(db, -1);
   248    250     return;
   249    251   
   250    252   detach_error:
   251    253     sqlite4_result_error(context, zErr, -1);
   252    254   }

Changes to src/callback.c.

    28     28       db->xCollNeeded(db->pCollNeededArg, db, enc, zExternal);
    29     29       sqlite4DbFree(db, zExternal);
    30     30     }
    31     31   #ifndef SQLITE4_OMIT_UTF16
    32     32     if( db->xCollNeeded16 ){
    33     33       char const *zExternal;
    34     34       sqlite4_value *pTmp = sqlite4ValueNew(db);
    35         -    sqlite4ValueSetStr(pTmp, -1, zName, SQLITE4_UTF8, SQLITE4_STATIC);
           35  +    sqlite4ValueSetStr(pTmp, -1, zName, SQLITE4_UTF8, SQLITE4_STATIC, 0);
    36     36       zExternal = sqlite4ValueText(pTmp, SQLITE4_UTF16NATIVE);
    37     37       if( zExternal ){
    38     38         db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal);
    39     39       }
    40     40       sqlite4ValueFree(pTmp);
    41     41     }
    42     42   #endif

Changes to src/complete.c.

   265    265     int rc = SQLITE4_NOMEM;
   266    266   
   267    267   #ifndef SQLITE4_OMIT_AUTOINIT
   268    268     rc = sqlite4_initialize(0);
   269    269     if( rc ) return rc;
   270    270   #endif
   271    271     pVal = sqlite4ValueNew(0);
   272         -  sqlite4ValueSetStr(pVal, -1, zSql, SQLITE4_UTF16NATIVE, SQLITE4_STATIC);
          272  +  sqlite4ValueSetStr(pVal, -1, zSql, SQLITE4_UTF16NATIVE, SQLITE4_STATIC, 0);
   273    273     zSql8 = sqlite4ValueText(pVal, SQLITE4_UTF8);
   274    274     if( zSql8 ){
   275    275       rc = sqlite4_complete(zSql8);
   276    276     }else{
   277    277       rc = SQLITE4_NOMEM;
   278    278     }
   279    279     sqlite4ValueFree(pVal);
   280    280     return sqlite4ApiExit(0, rc);
   281    281   }
   282    282   #endif /* SQLITE4_OMIT_UTF16 */
   283    283   #endif /* SQLITE4_OMIT_COMPLETE */

Changes to src/date.c.

   810    810   ){
   811    811     DateTime x;
   812    812     if( isDate(context, argc, argv, &x)==0 ){
   813    813       char zBuf[100];
   814    814       computeYMD_HMS(&x);
   815    815       sqlite4_snprintf(zBuf,sizeof(zBuf), "%04d-%02d-%02d %02d:%02d:%02d",
   816    816                        x.Y, x.M, x.D, x.h, x.m, (int)(x.s));
   817         -    sqlite4_result_text(context, zBuf, -1, SQLITE4_TRANSIENT);
          817  +    sqlite4_result_text(context, zBuf, -1, SQLITE4_TRANSIENT, 0);
   818    818     }
   819    819   }
   820    820   
   821    821   /*
   822    822   **    time( TIMESTRING, MOD, MOD, ...)
   823    823   **
   824    824   ** Return HH:MM:SS
................................................................................
   829    829     sqlite4_value **argv
   830    830   ){
   831    831     DateTime x;
   832    832     if( isDate(context, argc, argv, &x)==0 ){
   833    833       char zBuf[100];
   834    834       computeHMS(&x);
   835    835       sqlite4_snprintf(zBuf,sizeof(zBuf), "%02d:%02d:%02d", x.h, x.m, (int)x.s);
   836         -    sqlite4_result_text(context, zBuf, -1, SQLITE4_TRANSIENT);
          836  +    sqlite4_result_text(context, zBuf, -1, SQLITE4_TRANSIENT, 0);
   837    837     }
   838    838   }
   839    839   
   840    840   /*
   841    841   **    date( TIMESTRING, MOD, MOD, ...)
   842    842   **
   843    843   ** Return YYYY-MM-DD
................................................................................
   848    848     sqlite4_value **argv
   849    849   ){
   850    850     DateTime x;
   851    851     if( isDate(context, argc, argv, &x)==0 ){
   852    852       char zBuf[100];
   853    853       computeYMD(&x);
   854    854       sqlite4_snprintf(zBuf,sizeof(zBuf), "%04d-%02d-%02d", x.Y, x.M, x.D);
   855         -    sqlite4_result_text(context, zBuf, -1, SQLITE4_TRANSIENT);
          855  +    sqlite4_result_text(context, zBuf, -1, SQLITE4_TRANSIENT, 0);
   856    856     }
   857    857   }
   858    858   
   859    859   /*
   860    860   **    strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
   861    861   **
   862    862   ** Return a string described by FORMAT.  Conversions as follows:
................................................................................
   996    996           }
   997    997           default:   z[j++] = '%'; break;
   998    998         }
   999    999       }
  1000   1000     }
  1001   1001     z[j] = 0;
  1002   1002     sqlite4_result_text(context, z, -1,
  1003         -                      z==zBuf ? SQLITE4_TRANSIENT : SQLITE4_DYNAMIC);
         1003  +                      z==zBuf ? SQLITE4_TRANSIENT : SQLITE4_DYNAMIC, 0);
  1004   1004   }
  1005   1005   
  1006   1006   /*
  1007   1007   ** current_time()
  1008   1008   **
  1009   1009   ** This function returns the same value as time('now').
  1010   1010   */
................................................................................
  1083   1083     sqlite4_mutex_enter(sqlite4MutexAlloc(SQLITE4_MUTEX_STATIC_MASTER));
  1084   1084     pTm = gmtime(&t);
  1085   1085     if( pTm ) memcpy(&sNow, pTm, sizeof(sNow));
  1086   1086     sqlite4_mutex_leave(sqlite4MutexAlloc(SQLITE4_MUTEX_STATIC_MASTER));
  1087   1087   #endif
  1088   1088     if( pTm ){
  1089   1089       strftime(zBuf, 20, zFormat, &sNow);
  1090         -    sqlite4_result_text(context, zBuf, -1, SQLITE4_TRANSIENT);
         1090  +    sqlite4_result_text(context, zBuf, -1, SQLITE4_TRANSIENT, 0);
  1091   1091     }
  1092   1092   }
  1093   1093   #endif
  1094   1094   
  1095   1095   /*
  1096   1096   ** This function registered all of the above C functions as SQL
  1097   1097   ** functions.  This should be the only routine in this file with

Changes to src/delete.c.

   114    114     }
   115    115     sqlite4SelectDestInit(&dest, SRT_EphemTab, iCur);
   116    116     sqlite4Select(pParse, pDup, &dest);
   117    117     sqlite4SelectDelete(db, pDup);
   118    118   }
   119    119   #endif /* !defined(SQLITE4_OMIT_VIEW) && !defined(SQLITE4_OMIT_TRIGGER) */
   120    120   
   121         -#if defined(SQLITE4_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE4_OMIT_SUBQUERY)
          121  +#if defined(SQLITE4_ENABLE_UPDATE_DELETE_LIMIT) \
          122  + && !defined(SQLITE4_OMIT_SUBQUERY)
   122    123   /*
   123    124   ** Generate an expression tree to implement the WHERE, ORDER BY,
   124    125   ** and LIMIT/OFFSET portion of DELETE and UPDATE statements.
   125    126   **
   126    127   **     DELETE FROM table_wxyz WHERE a<5 ORDER BY a LIMIT 1;
   127    128   **                            \__________________________/
   128    129   **                               pLimitWhere (pInClause)
   129    130   */
   130    131   Expr *sqlite4LimitWhere(
   131         -  Parse *pParse,               /* The parser context */
   132         -  SrcList *pSrc,               /* the FROM clause -- which tables to scan */
   133         -  Expr *pWhere,                /* The WHERE clause.  May be null */
   134         -  ExprList *pOrderBy,          /* The ORDER BY clause.  May be null */
   135         -  Expr *pLimit,                /* The LIMIT clause.  May be null */
   136         -  Expr *pOffset,               /* The OFFSET clause.  May be null */
   137         -  char *zStmtType              /* Either DELETE or UPDATE.  For error messages. */
          132  +  Parse *pParse,            /* The parser context */
          133  +  SrcList *pSrc,            /* the FROM clause -- which tables to scan */
          134  +  Expr *pWhere,             /* The WHERE clause.  May be null */
          135  +  ExprList *pOrderBy,       /* The ORDER BY clause.  May be null */
          136  +  Expr *pLimit,             /* The LIMIT clause.  May be null */
          137  +  Expr *pOffset,            /* The OFFSET clause.  May be null */
          138  +  char *zStmtType           /* Either DELETE or UPDATE. For error messages. */
   138    139   ){
   139         -  Expr *pWhereRowid = NULL;    /* WHERE rowid .. */
   140         -  Expr *pInClause = NULL;      /* WHERE rowid IN ( select ) */
   141         -  Expr *pSelectRowid = NULL;   /* SELECT rowid ... */
   142         -  ExprList *pEList = NULL;     /* Expression list contaning only pSelectRowid */
   143         -  SrcList *pSelectSrc = NULL;  /* SELECT rowid FROM x ... (dup of pSrc) */
   144         -  Select *pSelect = NULL;      /* Complete SELECT tree */
          140  +  Expr *pWhereRowid = NULL; /* WHERE rowid .. */
          141  +  Expr *pInClause = NULL;   /* WHERE rowid IN ( select ) */
          142  +  Expr *pSelectRowid = NULL;/* SELECT rowid ... */
          143  +  ExprList *pEList = NULL;  /* Expression list contaning only pSelectRowid */
          144  +  SrcList *pSelectSrc = NULL;/* SELECT rowid FROM x ... (dup of pSrc) */
          145  +  Select *pSelect = NULL;   /* Complete SELECT tree */
   145    146   
   146    147     /* Check that there isn't an ORDER BY without a LIMIT clause.
   147    148     */
   148    149     if( pOrderBy && (pLimit == 0) ) {
   149    150       sqlite4ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
   150    151       goto limit_where_cleanup_2;
   151    152     }
................................................................................
   205    206   limit_where_cleanup_2:
   206    207     sqlite4ExprDelete(pParse->db, pWhere);
   207    208     sqlite4ExprListDelete(pParse->db, pOrderBy);
   208    209     sqlite4ExprDelete(pParse->db, pLimit);
   209    210     sqlite4ExprDelete(pParse->db, pOffset);
   210    211     return 0;
   211    212   }
   212         -#endif /* defined(SQLITE4_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE4_OMIT_SUBQUERY) */
          213  +#endif /* defined(SQLITE4_ENABLE_UPDATE_DELETE_LIMIT) */
          214  +       /* && !defined(SQLITE4_OMIT_SUBQUERY) */
   213    215   
   214    216   /*
   215    217   ** Generate code for a DELETE FROM statement.
   216    218   **
   217    219   **     DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL;
   218    220   **                 \________/       \________________/
   219    221   **                  pTabList              pWhere
................................................................................
   261    263     ** delete.  */
   262    264     if( sqlite4IsReadOnly(pParse, pTab, pTrigger!=0) ) goto delete_from_cleanup;
   263    265     assert( !IsView(pTab) || pTrigger );
   264    266     assert( !IsView(pTab) || pTab->pIndex==0 );
   265    267   
   266    268     /* Invoke the authorization callback */
   267    269     rcauth = sqlite4AuthCheck(pParse, SQLITE4_DELETE, pTab->zName, 0, zDb);
   268         -  assert( rcauth==SQLITE4_OK || rcauth==SQLITE4_DENY || rcauth==SQLITE4_IGNORE );
          270  +  assert( rcauth==SQLITE4_OK || rcauth==SQLITE4_DENY
          271  +         || rcauth==SQLITE4_IGNORE );
   269    272     if( rcauth==SQLITE4_DENY ){
   270    273       goto delete_from_cleanup;
   271    274     }
   272    275   
   273    276     /* Assign a cursor number to the table or view this statement is 
   274    277     ** deleting from. If pTab is actually a view, this will be used as the
   275    278     ** ephemeral table cursor. 

Added src/env.c.

            1  +/*
            2  +** 2013 January 7
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +** 
           13  +** This file contains code used to help implement the sqlite4_env object.
           14  +*/
           15  +#include "sqliteInt.h"
           16  +
           17  +
           18  +/*
           19  +** Default factory objects
           20  +*/
           21  +static KVFactory memFactory = {
           22  +   0,
           23  +   "temp",
           24  +   sqlite4KVStoreOpenMem,
           25  +   1
           26  +};
           27  +KVFactory sqlite4BuiltinFactory = {
           28  +   &memFactory,
           29  +   "main",
           30  +   sqlite4KVStoreOpenLsm,
           31  +   1
           32  +};
           33  +
           34  +/*
           35  +** The following singleton contains the global configuration for
           36  +** the SQLite library.
           37  +*/
           38  +struct sqlite4_env sqlite4DefaultEnv = {
           39  +   sizeof(sqlite4_env),       /* nByte */
           40  +   1,                         /* iVersion */
           41  +   SQLITE4_DEFAULT_MEMSTATUS, /* bMemstat */
           42  +   1,                         /* bCoreMutex */
           43  +   SQLITE4_THREADSAFE==1,     /* bFullMutex */
           44  +   0x7ffffffe,                /* mxStrlen */
           45  +   128,                       /* szLookaside */
           46  +   500,                       /* nLookaside */
           47  +   &sqlite4MMSystem,          /* pMM */
           48  +   {0,0,0,0,0,0,0,0,0},       /* m */
           49  +   {0,0,0,0,0,0,0,0,0,0},     /* mutex */
           50  +   (void*)0,                  /* pHeap */
           51  +   0,                         /* nHeap */
           52  +   0, 0,                      /* mnHeap, mxHeap */
           53  +   0,                         /* mxParserStack */
           54  +   &sqlite4BuiltinFactory,    /* pFactory */
           55  +   sqlite4OsRandomness,       /* xRandomness */
           56  +   sqlite4OsCurrentTime,      /* xCurrentTime */
           57  +   /* All the rest should always be initialized to zero */
           58  +   0,                         /* isInit */
           59  +   0,                         /* pFactoryMutex */
           60  +   0,                         /* pPrngMutex */
           61  +   0, 0,                      /* prngX, prngY */
           62  +   0,                         /* xLog */
           63  +   0,                         /* pLogArg */
           64  +   0,                         /* bLocaltimeFault */
           65  +   0,                         /* pMemMutex */
           66  +   {0,0,0,0},                 /* nowValue[] */
           67  +   {0,0,0,0},                 /* mxValue[] */
           68  +   {0,}                       /* hashGlobalFunc */
           69  +};
           70  +
           71  +/*
           72  +** Return the default environment
           73  +*/
           74  +sqlite4_env *sqlite4_env_default(void){ return &sqlite4DefaultEnv; }
           75  +
           76  +/*
           77  +** Initialize SQLite.  
           78  +**
           79  +** This routine must be called to initialize the run-time environment
           80  +** As long as you do not compile with SQLITE4_OMIT_AUTOINIT
           81  +** this routine will be called automatically by key routines such as
           82  +** sqlite4_open().  
           83  +**
           84  +** This routine is a no-op except on its very first call for a given
           85  +** sqlite4_env object, or for the first call after a call to sqlite4_shutdown.
           86  +**
           87  +** This routine is not threadsafe.  It should be called from a single
           88  +** thread to initialized the library in a multi-threaded system.  Other
           89  +** threads should avoid using the sqlite4_env object until after it has
           90  +** completely initialized.
           91  +*/
           92  +int sqlite4_initialize(sqlite4_env *pEnv){
           93  +  MUTEX_LOGIC( sqlite4_mutex *pMaster; )       /* The main static mutex */
           94  +  int rc;                                      /* Result code */
           95  +
           96  +  if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;
           97  +
           98  +  /* If SQLite is already completely initialized, then this call
           99  +  ** to sqlite4_initialize() should be a no-op.  But the initialization
          100  +  ** must be complete.  So isInit must not be set until the very end
          101  +  ** of this routine.
          102  +  */
          103  +  if( pEnv->isInit ) return SQLITE4_OK;
          104  +
          105  +  /* Initialize the mutex subsystem
          106  +  */
          107  +  rc = sqlite4MutexInit(pEnv);
          108  +  if( rc ){
          109  +    sqlite4MallocEnd(pEnv);
          110  +    return rc;
          111  +  }
          112  +
          113  +  /* Initialize the memory allocation subsystem
          114  +  */
          115  +  rc = sqlite4MallocInit(pEnv);
          116  +  if( rc ) return rc;
          117  +
          118  +  /* Create required mutexes
          119  +  */
          120  +  if( pEnv->bCoreMutex ){
          121  +    pEnv->pMemMutex = sqlite4MutexAlloc(pEnv, SQLITE4_MUTEX_FAST);
          122  +    pEnv->pPrngMutex = sqlite4MutexAlloc(pEnv, SQLITE4_MUTEX_FAST);
          123  +    pEnv->pFactoryMutex = sqlite4MutexAlloc(pEnv, SQLITE4_MUTEX_FAST);
          124  +    if( pEnv->pMemMutex==0
          125  +     || pEnv->pPrngMutex==0
          126  +     || pEnv->pFactoryMutex==0
          127  +    ){
          128  +      rc = SQLITE4_NOMEM;
          129  +    }
          130  +  }else{
          131  +    pEnv->pMemMutex = 0;
          132  +    pEnv->pPrngMutex = 0;
          133  +  }
          134  +  pEnv->isInit = 1;
          135  +
          136  +  sqlite4OsInit(pEnv);
          137  +
          138  +  /* Register global functions */
          139  +  if( rc==SQLITE4_OK ){
          140  +    sqlite4RegisterGlobalFunctions(pEnv);
          141  +  }
          142  +
          143  +  /* The following is just a sanity check to make sure SQLite has
          144  +  ** been compiled correctly.  It is important to run this code, but
          145  +  ** we don't want to run it too often and soak up CPU cycles for no
          146  +  ** reason.  So we run it once during initialization.
          147  +  */
          148  +#ifndef NDEBUG
          149  +#ifndef SQLITE4_OMIT_FLOATING_POINT
          150  +  /* This section of code's only "output" is via assert() statements. */
          151  +  if ( rc==SQLITE4_OK ){
          152  +    u64 x = (((u64)1)<<63)-1;
          153  +    double y;
          154  +    assert(sizeof(x)==8);
          155  +    assert(sizeof(x)==sizeof(y));
          156  +    memcpy(&y, &x, 8);
          157  +    assert( sqlite4IsNaN(y) );
          158  +  }
          159  +#endif
          160  +#endif
          161  +
          162  +  return rc;
          163  +}
          164  +
          165  +/*
          166  +** Undo the effects of sqlite4_initialize().  Must not be called while
          167  +** there are outstanding database connections or memory allocations or
          168  +** while any part of SQLite is otherwise in use in any thread.  This
          169  +** routine is not threadsafe.  But it is safe to invoke this routine
          170  +** on when SQLite is already shut down.  If SQLite is already shut down
          171  +** when this routine is invoked, then this routine is a harmless no-op.
          172  +*/
          173  +int sqlite4_shutdown(sqlite4_env *pEnv){
          174  +  if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;
          175  +  if( pEnv->isInit ){
          176  +    KVFactory *pMkr;
          177  +    sqlite4_mutex_free(pEnv->pFactoryMutex);
          178  +    sqlite4_mutex_free(pEnv->pPrngMutex);
          179  +    sqlite4_mutex_free(pEnv->pMemMutex);
          180  +    pEnv->pMemMutex = 0;
          181  +    while( (pMkr = pEnv->pFactory)!=0 && pMkr->isPerm==0 ){
          182  +      KVFactory *pNext = pMkr->pNext;
          183  +      sqlite4_free(pEnv, pMkr);
          184  +      pMkr = pNext;
          185  +    }
          186  +    sqlite4MutexEnd(pEnv);
          187  +    sqlite4MallocEnd(pEnv);
          188  +    pEnv->isInit = 0;
          189  +  }
          190  +  return SQLITE4_OK;
          191  +}
          192  +
          193  +/*
          194  +** Return the size of an sqlite4_env object
          195  +*/
          196  +int sqlite4_env_size(void){ return sizeof(sqlite4_env); }
          197  +
          198  +/*
          199  +** This API allows applications to modify the configuration described by
          200  +** an sqlite4_env object.
          201  +*/
          202  +int sqlite4_env_config(sqlite4_env *pEnv, int op, ...){
          203  +  va_list ap;
          204  +  int rc = SQLITE4_OK;
          205  +
          206  +  if( pEnv==0 ) pEnv = sqlite4_env_default();
          207  +
          208  +  va_start(ap, op);
          209  +  switch( op ){
          210  +    /*
          211  +    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_INIT, template);
          212  +    **
          213  +    ** Turn bulk memory into a new sqlite4_env object.  The template is
          214  +    ** a prior sqlite4_env that is used as a template in initializing the
          215  +    ** new sqlite4_env object.  The size of the bulk memory must be at
          216  +    ** least as many bytes as returned from sqlite4_env_size().
          217  +    */
          218  +    case SQLITE4_ENVCONFIG_INIT: {
          219  +      /* Disable all mutexing */
          220  +      sqlite4_env *pTemplate = va_arg(ap, sqlite4_env*);
          221  +      int n = pTemplate->nByte;
          222  +      if( n>sizeof(sqlite4_env) ) n = sizeof(sqlite4_env);
          223  +      memcpy(pEnv, pTemplate, n);
          224  +      pEnv->pFactory = &sqlite4BuiltinFactory;
          225  +      pEnv->isInit = 0;
          226  +      break;
          227  +    }
          228  +
          229  +    /* Mutex configuration options are only available in a threadsafe
          230  +    ** compile. 
          231  +    */
          232  +#if defined(SQLITE4_THREADSAFE) && SQLITE4_THREADSAFE>0
          233  +    /*
          234  +    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_SINGLETHREAD);
          235  +    **
          236  +    ** Configure this environment for a single-threaded application.
          237  +    */
          238  +    case SQLITE4_ENVCONFIG_SINGLETHREAD: {
          239  +      /* Disable all mutexing */
          240  +      if( pEnv->isInit ){ rc = SQLITE4_MISUSE; break; }
          241  +      pEnv->bCoreMutex = 0;
          242  +      pEnv->bFullMutex = 0;
          243  +      break;
          244  +    }
          245  +
          246  +    /*
          247  +    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_MULTITHREAD);
          248  +    **
          249  +    ** Configure this environment for a multi-threaded application where
          250  +    ** the same database connection is never used by more than a single
          251  +    ** thread at a time.
          252  +    */
          253  +    case SQLITE4_ENVCONFIG_MULTITHREAD: {
          254  +      /* Disable mutexing of database connections */
          255  +      /* Enable mutexing of core data structures */
          256  +      if( pEnv->isInit ){ rc = SQLITE4_MISUSE; break; }
          257  +      pEnv->bCoreMutex = 1;
          258  +      pEnv->bFullMutex = 0;
          259  +      break;
          260  +    }
          261  +
          262  +    /*
          263  +    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_SERIALIZED);
          264  +    **
          265  +    ** Configure this environment for an unrestricted multi-threaded
          266  +    ** application where any thread can do whatever it wants with any
          267  +    ** database connection at any time.
          268  +    */
          269  +    case SQLITE4_ENVCONFIG_SERIALIZED: {
          270  +      /* Enable all mutexing */
          271  +      if( pEnv->isInit ){ rc = SQLITE4_MISUSE; break; }
          272  +      pEnv->bCoreMutex = 1;
          273  +      pEnv->bFullMutex = 1;
          274  +      break;
          275  +    }
          276  +
          277  +    /*
          278  +    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_MUTEXT, sqlite4_mutex_methods*)
          279  +    **
          280  +    ** Configure this environment to use the mutex routines specified by the
          281  +    ** argument.
          282  +    */
          283  +    case SQLITE4_ENVCONFIG_MUTEX: {
          284  +      /* Specify an alternative mutex implementation */
          285  +      if( pEnv->isInit ){ rc = SQLITE4_MISUSE; break; }
          286  +      pEnv->mutex = *va_arg(ap, sqlite4_mutex_methods*);
          287  +      break;
          288  +    }
          289  +
          290  +    /*
          291  +    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_GETMUTEX, sqlite4_mutex_methods*)
          292  +    **
          293  +    ** Copy the mutex routines in use by this environment into the structure
          294  +    ** given in the argument.
          295  +    */
          296  +    case SQLITE4_ENVCONFIG_GETMUTEX: {
          297  +      /* Retrieve the current mutex implementation */
          298  +      *va_arg(ap, sqlite4_mutex_methods*) = pEnv->mutex;
          299  +      break;
          300  +    }
          301  +#endif
          302  +
          303  +
          304  +    /*
          305  +    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_MALLOC, sqlite4_mem_methods*)
          306  +    **
          307  +    ** Set the memory allocation routines to be used by this environment.
          308  +    */
          309  +    case SQLITE4_ENVCONFIG_MALLOC: {
          310  +      /* Specify an alternative malloc implementation */
          311  +      if( pEnv->isInit ) return SQLITE4_MISUSE;
          312  +      pEnv->m = *va_arg(ap, sqlite4_mem_methods*);
          313  +      break;
          314  +    }
          315  +
          316  +    /*
          317  +    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_GETMALLOC, sqlite4_mem_methods*)
          318  +    **
          319  +    ** Copy the memory allocation routines in use by this environment
          320  +    ** into the structure given in the argument.
          321  +    */
          322  +    case SQLITE4_ENVCONFIG_GETMALLOC: {
          323  +      /* Retrieve the current malloc() implementation */
          324  +      if( pEnv->m.xMalloc==0 ) sqlite4MemSetDefault(pEnv);
          325  +      *va_arg(ap, sqlite4_mem_methods*) = pEnv->m;
          326  +      break;
          327  +    }
          328  +
          329  +    /* sqlite4_env_config(p, SQLITE4_ENVCONFIG_MEMSTAT, int onoff);
          330  +    **
          331  +    ** Enable or disable collection of memory usage statistics according to
          332  +    ** the onoff parameter.  
          333  +    */
          334  +    case SQLITE4_ENVCONFIG_MEMSTATUS: {
          335  +      /* Enable or disable the malloc status collection */
          336  +      pEnv->bMemstat = va_arg(ap, int);
          337  +      break;
          338  +    }
          339  +
          340  +    /*
          341  +    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_LOOKASIDE, size, count);
          342  +    **
          343  +    ** Set the default lookaside memory settings for all subsequent
          344  +    ** database connections constructed in this environment.  The size
          345  +    ** parameter is the size of each lookaside memory buffer and the
          346  +    ** count parameter is the number of lookaside buffers.  Set both
          347  +    ** to zero to disable lookaside memory.
          348  +    */
          349  +    case SQLITE4_ENVCONFIG_LOOKASIDE: {
          350  +      pEnv->szLookaside = va_arg(ap, int);
          351  +      pEnv->nLookaside = va_arg(ap, int);
          352  +      break;
          353  +    }
          354  +    
          355  +    /*
          356  +    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_LOG, xOutput, pArg);
          357  +    **
          358  +    ** Set the log function that is called in response to sqlite4_log()
          359  +    ** calls.
          360  +    */
          361  +    case SQLITE4_ENVCONFIG_LOG: {
          362  +      /* MSVC is picky about pulling func ptrs from va lists.
          363  +      ** http://support.microsoft.com/kb/47961
          364  +      ** pEnv->xLog = va_arg(ap, void(*)(void*,int,const char*));
          365  +      */
          366  +      typedef void(*LOGFUNC_t)(void*,int,const char*);
          367  +      pEnv->xLog = va_arg(ap, LOGFUNC_t);
          368  +      pEnv->pLogArg = va_arg(ap, void*);
          369  +      break;
          370  +    }
          371  +
          372  +    /*
          373  +    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_KVSTORE_PUSH, zName,xFactory);
          374  +    **
          375  +    ** Push a new KVStore factory onto the factory stack.  The new factory
          376  +    ** takes priority over prior factories.
          377  +    */
          378  +    case SQLITE4_ENVCONFIG_KVSTORE_PUSH: {
          379  +      const char *zName = va_arg(ap, const char*);
          380  +      int nName = sqlite4Strlen30(zName);
          381  +      KVFactory *pMkr = sqlite4_malloc(pEnv, sizeof(*pMkr)+nName+1);
          382  +      char *z;
          383  +      if( pMkr==0 ) return SQLITE4_NOMEM;
          384  +      z = (char*)&pMkr[1];
          385  +      memcpy(z, zName, nName+1);
          386  +      memset(pMkr, 0, sizeof(*pMkr));
          387  +      pMkr->zName = z;
          388  +      pMkr->xFactory = va_arg(ap, sqlite4_kvfactory);
          389  +      sqlite4_mutex_enter(pEnv->pFactoryMutex);
          390  +      pMkr->pNext = pEnv->pFactory;
          391  +      pEnv->pFactory = pMkr;
          392  +      sqlite4_mutex_leave(pEnv->pFactoryMutex);
          393  +      break;
          394  +    }
          395  +
          396  +    /*
          397  +    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_KVSTORE_POP, zName, &pxFact);
          398  +    **
          399  +    ** Remove a KVStore factory from the stack.
          400  +    */
          401  +    /*
          402  +    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_KVSTORE_GET, zName, &pxFact);
          403  +    **
          404  +    ** Get the current factory pointer with the given name but leave the
          405  +    ** factory on the stack.
          406  +    */
          407  +    case SQLITE4_ENVCONFIG_KVSTORE_POP:
          408  +    case SQLITE4_ENVCONFIG_KVSTORE_GET: {
          409  +      typedef int (**PxFact)(sqlite4_env*,KVStore**,const char*,unsigned);
          410  +      const char *zName = va_arg(ap, const char*);
          411  +      KVFactory *pMkr, **ppPrev;
          412  +      PxFact pxFact;
          413  +
          414  +      pxFact = va_arg(ap,PxFact);
          415  +      *pxFact = 0;
          416  +      sqlite4_mutex_enter(pEnv->pFactoryMutex);
          417  +      ppPrev = &pEnv->pFactory;
          418  +      pMkr = *ppPrev;
          419  +      while( pMkr && strcmp(zName, pMkr->zName)!=0 ){
          420  +        ppPrev = &pMkr->pNext;
          421  +        pMkr = *ppPrev;
          422  +      }
          423  +      if( pMkr ){
          424  +        *pxFact = pMkr->xFactory;
          425  +        if( op==SQLITE4_ENVCONFIG_KVSTORE_POP && pMkr->isPerm==0 ){
          426  +          *ppPrev = pMkr->pNext;
          427  +          sqlite4_free(pEnv, pMkr);
          428  +        }
          429  +      }
          430  +      sqlite4_mutex_leave(pEnv->pFactoryMutex);
          431  +      break;
          432  +    }
          433  +
          434  +
          435  +    default: {
          436  +      rc = SQLITE4_ERROR;
          437  +      break;
          438  +    }
          439  +  }
          440  +  va_end(ap);
          441  +  return rc;
          442  +}

Changes to src/expr.c.

   362    362   ** for this node and for the pToken argument is a single allocation
   363    363   ** obtained from sqlite4DbMalloc().  The calling function
   364    364   ** is responsible for making sure the node eventually gets freed.
   365    365   **
   366    366   ** If dequote is true, then the token (if it exists) is dequoted.
   367    367   ** If dequote is false, no dequoting is performance.  The deQuote
   368    368   ** parameter is ignored if pToken is NULL or if the token does not
   369         -** appear to be quoted.  If the quotes were of the form "..." (double-quotes)
   370         -** then the EP_DblQuoted flag is set on the expression node.
          369  +** appear to be quoted.
   371    370   **
   372    371   ** Special case:  If op==TK_INTEGER and pToken points to a string that
   373    372   ** can be translated into a 32-bit integer, then the token is not
   374    373   ** stored in u.zToken.  Instead, the integer values is written
   375    374   ** into u.iValue and the EP_IntValue flag is set.  No extra storage
   376    375   ** is allocated to hold the integer text and the dequote flag is ignored.
   377    376   */
................................................................................
   403    402         }else{
   404    403           int c;
   405    404           pNew->u.zToken = (char*)&pNew[1];
   406    405           assert( pToken->z!=0 || pToken->n==0 );
   407    406           if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
   408    407           pNew->u.zToken[pToken->n] = 0;
   409    408           if( dequote && nExtra>=3 
   410         -             && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
          409  +             && ((c = pToken->z[0])=='\'' || c=='"' || c=='[') ){
   411    410             sqlite4Dequote(pNew->u.zToken);
   412         -          if( c=='"' ) pNew->flags |= EP_DblQuoted;
   413    411           }
   414    412         }
   415    413       }
   416    414   #if SQLITE4_MAX_EXPR_DEPTH>0
   417    415       pNew->nHeight = 1;
   418    416   #endif  
   419    417     }

Changes to src/fts5.c.

  3392   3392       if( zErr==0 ){
  3393   3393         zErr = sqlite4MPrintf(db, "error parsing expression: %d", rc);
  3394   3394       }
  3395   3395       goto fts5_parse_expr_out;
  3396   3396     }
  3397   3397   
  3398   3398     fts5PrintExpr(db, azCol, pExpr, &zRet);
  3399         -  sqlite4_result_text(pCtx, zRet, -1, SQLITE4_TRANSIENT);
         3399  +  sqlite4_result_text(pCtx, zRet, -1, SQLITE4_TRANSIENT, 0);
  3400   3400     fts5ExpressionFree(db, pExpr);
  3401   3401     sqlite4_free(sqlite4_db_env(db), zRet);
  3402   3402   
  3403   3403    fts5_parse_expr_out:
  3404   3404     if( p ) pTok->xDestroy(p);
  3405   3405     sqlite4DbFree(db, azCol);
  3406   3406     sqlite4_finalize(pStmt);
................................................................................
  3419   3419     int rc = sqlite4_create_function(
  3420   3420         db, "fts5_parse_expr", 3, SQLITE4_UTF8, 0, fts5_parse_expr, 0, 0
  3421   3421     );
  3422   3422     if( rc!=SQLITE4_OK ) return rc;
  3423   3423   #endif
  3424   3424     return sqlite4InitFts5Func(db);
  3425   3425   }
  3426         -

Changes to src/fts5func.c.

    45     45   struct Fts5RankCtx {
    46     46     sqlite4 *db;
    47     47     double *aAvgdl;                 /* Average document size of each field */
    48     48     int nPhrase;                    /* Number of phrases in query */
    49     49     double *aIdf;                   /* IDF weights for each phrase in query */
    50     50   };
    51     51   
    52         -static void fts5RankFreeCtx(void *pCtx){
           52  +static void fts5RankFreeCtx(void *pNotUsed, void *pCtx){
    53     53     if( pCtx ){
    54     54       Fts5RankCtx *p = (Fts5RankCtx *)pCtx;
    55     55       sqlite4DbFree(p->db, p);
    56     56     }
    57     57   }
    58     58   
    59     59   #define BM25_EXPLAIN  0x01
................................................................................
   132    132     if( p==0 ){
   133    133       int nPhrase;                  /* Number of phrases in query expression */
   134    134       int nByte;                    /* Number of bytes of data to allocate */
   135    135   
   136    136       sqlite4_mi_phrase_count(pCtx, &nPhrase);
   137    137       nByte = sizeof(Fts5RankCtx) + (nPhrase+nField) * sizeof(double);
   138    138       p = (Fts5RankCtx *)sqlite4DbMallocZero(db, nByte);
   139         -    sqlite4_set_auxdata(pCtx, 0, (void *)p, fts5RankFreeCtx);
          139  +    sqlite4_set_auxdata(pCtx, 0, (void *)p, fts5RankFreeCtx, 0);
   140    140       p = sqlite4_get_auxdata(pCtx, 0);
   141    141   
   142    142       if( !p ){
   143    143         rc = SQLITE4_NOMEM;
   144    144       }else{
   145    145         int N;                      /* Total number of docs in collection */
   146    146         int ni;                     /* Number of docs with phrase i */
................................................................................
   266    266     }
   267    267   
   268    268     if( rc==SQLITE4_OK ){
   269    269       if( bExplain ){
   270    270         zExplain = sqlite4MAppendf(
   271    271             db, zExplain, "%s</table><b>overall rank=%.2f</b>", zExplain, rank
   272    272         );
   273         -      sqlite4_result_text(pCtx, zExplain, -1, SQLITE4_TRANSIENT);
          273  +      sqlite4_result_text(pCtx, zExplain, -1, SQLITE4_TRANSIENT, 0);
   274    274       }else{
   275    275         sqlite4_result_double(pCtx, rank);
   276    276       }
   277    277     }else{
   278    278       sqlite4_result_error_code(pCtx, rc);
   279    279     }
   280    280     sqlite4DbFree(db, zExplain);
................................................................................
   542    542   
   543    543     iOff += nShift;
   544    544     mask = mask >> nShift;
   545    545   
   546    546     pSnip->iOff = iOff;
   547    547     pSnip->hlmask = mask;
   548    548   }
          549  +
          550  +/*
          551  +** Parameter aSnip points to an array of nSnip Snippet objects, where nSnip
          552  +** is less than or equal to 4. This function sorts the array in place in
          553  +** ascending order of Snippet.iCol and Snippet.iOff. 
          554  +*/
          555  +static void fts5SnippetSort(Snippet *aSnip, int nSnip){
          556  +  Snippet aTmp[4];
          557  +  int i;
          558  +
          559  +  assert( nSnip<=4 && nSnip>=1 );
          560  +
          561  +  for(i=0; i<nSnip; i++){
          562  +    int iBest = -1;
          563  +    int iTry;
          564  +    for(iTry=0; iTry<nSnip; iTry++){
          565  +      Snippet *pTry = &aSnip[iTry];
          566  +      if( pTry->iCol>=0 && (iBest<0 
          567  +         || pTry->iCol<aSnip[iBest].iCol
          568  +         || (pTry->iCol==aSnip[iBest].iCol && pTry->iOff<aSnip[iBest].iOff)
          569  +      )){
          570  +        iBest = iTry;
          571  +      }
          572  +    }
          573  +
          574  +    assert( iBest>=0 );
          575  +    memcpy(&aTmp[i], &aSnip[iBest], sizeof(Snippet));
          576  +    aSnip[iBest].iCol = -1;
          577  +  }
          578  +
          579  +  memcpy(aSnip, aTmp, sizeof(Snippet)*nSnip);
          580  +}
          581  +
   549    582   
   550    583   static void fts5Snippet(sqlite4_context *pCtx, int nArg, sqlite4_value **apArg){
   551    584     Snippet aSnip[4];
   552    585     int nSnip;
   553    586     int iCol = -1;
   554    587     int nToken = -15;
   555    588     int rc;
................................................................................
   579    612   
   580    613       memset(aSnip, 0, sizeof(aSnip));
   581    614       for(i=0; rc==SQLITE4_OK && i<nSnip; i++){
   582    615         rc = fts5BestSnippet(pCtx, iCol, &mask, nTok, &aSnip[i]);
   583    616       }
   584    617       if( mask==0 || nSnip==4 ){
   585    618         SnippetText text = {0, 0, 0};
          619  +      fts5SnippetSort(aSnip, nSnip);
   586    620         for(i=0; rc==SQLITE4_OK && i<nSnip; i++){
   587    621           int nSz;
   588    622           rc = sqlite4_mi_size(pCtx, aSnip[i].iCol, -1, &nSz);
   589    623           if( rc==SQLITE4_OK ){
   590    624             fts5SnippetImprove(pCtx, nTok, nSz, &aSnip[i]);
   591    625             rc = fts5SnippetText(
   592    626                 pCtx, &aSnip[i], &text, nTok, zStart, zEnd, zEllipses
   593    627             );
   594    628           }
   595    629         }
   596         -      sqlite4_result_text(pCtx, text.zOut, text.nOut, SQLITE4_TRANSIENT);
          630  +      sqlite4_result_text(pCtx, text.zOut, text.nOut, SQLITE4_TRANSIENT, 0);
   597    631         sqlite4DbFree(sqlite4_context_db_handle(pCtx), text.zOut);
   598    632         break;
   599    633       }
   600    634     }
   601    635   
   602    636     if( rc!=SQLITE4_OK ){
   603    637       sqlite4_result_error_code(pCtx, rc);
................................................................................
   666    700       void *p = SQLITE4_INT_TO_PTR(aRank[i].mask);
   667    701       const char *z = aRank[i].zName;
   668    702       rc = sqlite4_create_mi_function(db, z, -1, SQLITE4_UTF8, p, fts5Rank, 0);
   669    703     }
   670    704   
   671    705     return rc;
   672    706   }
   673         -

Changes to src/func.c.

    71     71     switch( sqlite4_value_type(argv[0]) ){
    72     72       case SQLITE4_INTEGER: z = "integer"; break;
    73     73       case SQLITE4_TEXT:    z = "text";    break;
    74     74       case SQLITE4_FLOAT:   z = "real";    break;
    75     75       case SQLITE4_BLOB:    z = "blob";    break;
    76     76       default:             z = "null";    break;
    77     77     }
    78         -  sqlite4_result_text(context, z, -1, SQLITE4_STATIC);
           78  +  sqlite4_result_text(context, z, -1, SQLITE4_STATIC, 0);
    79     79   }
    80     80   
    81     81   
    82     82   /*
    83     83   ** Implementation of the length() function
    84     84   */
    85     85   static void lengthFunc(
................................................................................
   240    240       while( *z && p1 ){
   241    241         SQLITE4_SKIP_UTF8(z);
   242    242         p1--;
   243    243       }
   244    244       for(z2=z; *z2 && p2; p2--){
   245    245         SQLITE4_SKIP_UTF8(z2);
   246    246       }
   247         -    sqlite4_result_text(context, (char*)z, (int)(z2-z), SQLITE4_TRANSIENT);
          247  +    sqlite4_result_text(context, (char*)z, (int)(z2-z), SQLITE4_TRANSIENT, 0);
   248    248     }else{
   249    249       if( p1+p2>len ){
   250    250         p2 = len-p1;
   251    251         if( p2<0 ) p2 = 0;
   252    252       }
   253         -    sqlite4_result_blob(context, (char*)&z[p1], (int)p2, SQLITE4_TRANSIENT);
          253  +    sqlite4_result_blob(context, (char*)&z[p1], (int)p2, SQLITE4_TRANSIENT, 0);
   254    254     }
   255    255   }
   256    256   
   257    257   /*
   258    258   ** Implementation of the round() function
   259    259   */
   260    260   #ifndef SQLITE4_OMIT_FLOATING_POINT
................................................................................
   332    332     assert( z2==(char*)sqlite4_value_text(argv[0]) );
   333    333     if( z2 ){
   334    334       z1 = contextMalloc(context, ((i64)n)+1);
   335    335       if( z1 ){
   336    336         for(i=0; i<n; i++){
   337    337           z1[i] = (char)sqlite4Toupper(z2[i]);
   338    338         }
   339         -      sqlite4_result_text(context, z1, n, SQLITE4_DYNAMIC);
          339  +      sqlite4_result_text(context, z1, n, SQLITE4_DYNAMIC, 0);
   340    340       }
   341    341     }
   342    342   }
   343    343   static void lowerFunc(sqlite4_context *context, int argc, sqlite4_value **argv){
   344    344     char *z1;
   345    345     const char *z2;
   346    346     int i, n;
................................................................................
   351    351     assert( z2==(char*)sqlite4_value_text(argv[0]) );
   352    352     if( z2 ){
   353    353       z1 = contextMalloc(context, ((i64)n)+1);
   354    354       if( z1 ){
   355    355         for(i=0; i<n; i++){
   356    356           z1[i] = sqlite4Tolower(z2[i]);
   357    357         }
   358         -      sqlite4_result_text(context, z1, n, SQLITE4_DYNAMIC);
          358  +      sqlite4_result_text(context, z1, n, SQLITE4_DYNAMIC, 0);
   359    359       }
   360    360     }
   361    361   }
   362    362   
   363    363   
   364    364   #if 0  /* This function is never used. */
   365    365   /*
................................................................................
   430    430     n = sqlite4_value_int(argv[0]);
   431    431     if( n<1 ){
   432    432       n = 1;
   433    433     }
   434    434     p = contextMalloc(context, n);
   435    435     if( p ){
   436    436       sqlite4_randomness(sqlite4_context_env(context), n, p);
   437         -    sqlite4_result_blob(context, (char*)p, n, SQLITE4_DYNAMIC);
          437  +    sqlite4_result_blob(context, (char*)p, n, SQLITE4_DYNAMIC, 0);
   438    438     }
   439    439   }
   440    440   
   441         -/*
   442         -** Implementation of the last_insert_rowid() SQL function.  The return
   443         -** value is the same as the sqlite4_last_insert_rowid() API function.
   444         -*/
   445         -static void last_insert_rowid(
   446         -  sqlite4_context *context, 
   447         -  int NotUsed, 
   448         -  sqlite4_value **NotUsed2
   449         -){
   450         -  sqlite4 *db = sqlite4_context_db_handle(context);
   451         -  UNUSED_PARAMETER2(NotUsed, NotUsed2);
   452         -  /* IMP: R-51513-12026 The last_insert_rowid() SQL function is a
   453         -  ** wrapper around the sqlite4_last_insert_rowid() C/C++ interface
   454         -  ** function. */
   455         -  sqlite4_result_int64(context, sqlite4_last_insert_rowid(db));
   456         -}
   457         -
   458    441   /*
   459    442   ** Implementation of the changes() SQL function.
   460    443   **
   461    444   ** IMP: R-62073-11209 The changes() SQL function is a wrapper
   462    445   ** around the sqlite4_changes() C/C++ function and hence follows the same
   463    446   ** rules for counting changes.
   464    447   */
................................................................................
   750    733     sqlite4_context *context,
   751    734     int NotUsed,
   752    735     sqlite4_value **NotUsed2
   753    736   ){
   754    737     UNUSED_PARAMETER2(NotUsed, NotUsed2);
   755    738     /* IMP: R-48699-48617 This function is an SQL wrapper around the
   756    739     ** sqlite4_libversion() C-interface. */
   757         -  sqlite4_result_text(context, sqlite4_libversion(), -1, SQLITE4_STATIC);
          740  +  sqlite4_result_text(context, sqlite4_libversion(), -1, SQLITE4_STATIC, 0);
   758    741   }
   759    742   
   760    743   /*
   761    744   ** Implementation of the sqlite_source_id() function. The result is a string
   762    745   ** that identifies the particular version of the source code used to build
   763    746   ** SQLite.
   764    747   */
................................................................................
   766    749     sqlite4_context *context,
   767    750     int NotUsed,
   768    751     sqlite4_value **NotUsed2
   769    752   ){
   770    753     UNUSED_PARAMETER2(NotUsed, NotUsed2);
   771    754     /* IMP: R-24470-31136 This function is an SQL wrapper around the
   772    755     ** sqlite4_sourceid() C interface. */
   773         -  sqlite4_result_text(context, sqlite4_sourceid(), -1, SQLITE4_STATIC);
          756  +  sqlite4_result_text(context, sqlite4_sourceid(), -1, SQLITE4_STATIC, 0);
   774    757   }
   775    758   
   776    759   /*
   777    760   ** Implementation of the sqlite_log() function.  This is a wrapper around
   778    761   ** sqlite4_log().  The return value is NULL.  The function exists purely for
   779    762   ** its side-effects.
   780    763   */
................................................................................
   826    809     int n;
   827    810     assert( argc==1 );
   828    811     UNUSED_PARAMETER(argc);
   829    812     /* IMP: R-04922-24076 The sqlite_compileoption_get() SQL function
   830    813     ** is a wrapper around the sqlite4_compileoption_get() C/C++ function.
   831    814     */
   832    815     n = sqlite4_value_int(argv[0]);
   833         -  sqlite4_result_text(context, sqlite4_compileoption_get(n), -1, SQLITE4_STATIC);
          816  +  sqlite4_result_text(context, sqlite4_compileoption_get(n), -1,
          817  +                      SQLITE4_STATIC, 0);
   834    818   }
   835    819   #endif /* SQLITE4_OMIT_COMPILEOPTION_DIAGS */
   836    820   
   837    821   /* Array for converting from half-bytes (nybbles) into ASCII hex
   838    822   ** digits. */
   839    823   static const char hexdigits[] = {
   840    824     '0', '1', '2', '3', '4', '5', '6', '7',
................................................................................
   873    857             zText[(i*2)+2] = hexdigits[(zBlob[i]>>4)&0x0F];
   874    858             zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F];
   875    859           }
   876    860           zText[(nBlob*2)+2] = '\'';
   877    861           zText[(nBlob*2)+3] = '\0';
   878    862           zText[0] = 'x';
   879    863           zText[1] = '\'';
   880         -        sqlite4_result_text(context, zText, -1, SQLITE4_TRANSIENT);
          864  +        sqlite4_result_text(context, zText, -1, SQLITE4_TRANSIENT, 0);
   881    865           sqlite4_free(sqlite4_context_env(context), zText);
   882    866         }
   883    867         break;
   884    868       }
   885    869       case SQLITE4_TEXT: {
   886    870         int i,j;
   887    871         u64 n;
................................................................................
   897    881             z[j++] = zArg[i];
   898    882             if( zArg[i]=='\'' ){
   899    883               z[j++] = '\'';
   900    884             }
   901    885           }
   902    886           z[j++] = '\'';
   903    887           z[j] = 0;
   904         -        sqlite4_result_text(context, z, j, SQLITE4_DYNAMIC);
          888  +        sqlite4_result_text(context, z, j, SQLITE4_DYNAMIC, 0);
   905    889         }
   906    890         break;
   907    891       }
   908    892       default: {
   909    893         assert( sqlite4_value_type(argv[0])==SQLITE4_NULL );
   910         -      sqlite4_result_text(context, "NULL", 4, SQLITE4_STATIC);
          894  +      sqlite4_result_text(context, "NULL", 4, SQLITE4_STATIC, 0);
   911    895         break;
   912    896       }
   913    897     }
   914    898   }
   915    899   
   916    900   /*
   917    901   ** The hex() function.  Interpret the argument as a blob.  Return
................................................................................
   934    918     if( zHex ){
   935    919       for(i=0; i<n; i++, pBlob++){
   936    920         unsigned char c = *pBlob;
   937    921         *(z++) = hexdigits[(c>>4)&0xf];
   938    922         *(z++) = hexdigits[c&0xf];
   939    923       }
   940    924       *z = 0;
   941         -    sqlite4_result_text(context, zHex, n*2, SQLITE4_DYNAMIC);
   942         -  }
   943         -}
   944         -
   945         -/*
   946         -** The zeroblob(N) function returns a zero-filled blob of size N bytes.
   947         -*/
   948         -static void zeroblobFunc(
   949         -  sqlite4_context *context,
   950         -  int argc,
   951         -  sqlite4_value **argv
   952         -){
   953         -  i64 n;
   954         -  sqlite4 *db = sqlite4_context_db_handle(context);
   955         -  assert( argc==1 );
   956         -  UNUSED_PARAMETER(argc);
   957         -  n = sqlite4_value_int64(argv[0]);
   958         -  testcase( n==db->aLimit[SQLITE4_LIMIT_LENGTH] );
   959         -  testcase( n==db->aLimit[SQLITE4_LIMIT_LENGTH]+1 );
   960         -  if( n>db->aLimit[SQLITE4_LIMIT_LENGTH] ){
   961         -    sqlite4_result_error_toobig(context);
   962         -  }else{
   963         -    sqlite4_result_zeroblob(context, (int)n); /* IMP: R-00293-64994 */
          925  +    sqlite4_result_text(context, zHex, n*2, SQLITE4_DYNAMIC, 0);
   964    926     }
   965    927   }
   966    928   
   967    929   /*
   968    930   ** The replace() function.  Three arguments are all strings: call
   969    931   ** them A, B, and C. The result is also a string which is derived
   970    932   ** from A by replacing every occurance of B with C.  The match
................................................................................
  1043   1005       }
  1044   1006     }
  1045   1007     assert( j+nStr-i+1==nOut );
  1046   1008     memcpy(&zOut[j], &zStr[i], nStr-i);
  1047   1009     j += nStr - i;
  1048   1010     assert( j<=nOut );
  1049   1011     zOut[j] = 0;
  1050         -  sqlite4_result_text(context, (char*)zOut, j, SQLITE4_DYNAMIC);
         1012  +  sqlite4_result_text(context, (char*)zOut, j, SQLITE4_DYNAMIC, 0);
  1051   1013   }
  1052   1014   
  1053   1015   /*
  1054   1016   ** Implementation of the TRIM(), LTRIM(), and RTRIM() functions.
  1055   1017   ** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both.
  1056   1018   */
  1057   1019   static void trimFunc(
................................................................................
  1127   1089           nIn -= len;
  1128   1090         }
  1129   1091       }
  1130   1092       if( zCharSet ){
  1131   1093         sqlite4_free(sqlite4_context_env(context), azChar);
  1132   1094       }
  1133   1095     }
  1134         -  sqlite4_result_text(context, (char*)zIn, nIn, SQLITE4_TRANSIENT);
         1096  +  sqlite4_result_text(context, (char*)zIn, nIn, SQLITE4_TRANSIENT, 0);
  1135   1097   }
  1136   1098   
  1137   1099   
  1138   1100   /* IMP: R-25361-16150 This function is omitted from SQLite by default. It
  1139   1101   ** is only available if the SQLITE4_SOUNDEX compile-time option is used
  1140   1102   ** when SQLite is built.
  1141   1103   */
................................................................................
  1182   1144           prevcode = 0;
  1183   1145         }
  1184   1146       }
  1185   1147       while( j<4 ){
  1186   1148         zResult[j++] = '0';
  1187   1149       }
  1188   1150       zResult[j] = 0;
  1189         -    sqlite4_result_text(context, zResult, 4, SQLITE4_TRANSIENT);
         1151  +    sqlite4_result_text(context, zResult, 4, SQLITE4_TRANSIENT, 0);
  1190   1152     }else{
  1191   1153       /* IMP: R-64894-50321 The string "?000" is returned if the argument
  1192   1154       ** is NULL or contains no ASCII alphabetic characters. */
  1193         -    sqlite4_result_text(context, "?000", 4, SQLITE4_STATIC);
         1155  +    sqlite4_result_text(context, "?000", 4, SQLITE4_STATIC, 0);
  1194   1156     }
  1195   1157   }
  1196   1158   #endif /* SQLITE4_SOUNDEX */
  1197   1159   
  1198   1160   #if 0 /*ndef SQLITE4_OMIT_LOAD_EXTENSION*/
  1199   1161   /*
  1200   1162   ** A function that loads a shared-library extension then returns NULL.
................................................................................
  1303   1265   */
  1304   1266   static void countStep(sqlite4_context *context, int argc, sqlite4_value **argv){
  1305   1267     CountCtx *p;
  1306   1268     p = sqlite4_aggregate_context(context, sizeof(*p));
  1307   1269     if( (argc==0 || SQLITE4_NULL!=sqlite4_value_type(argv[0])) && p ){
  1308   1270       p->n++;
  1309   1271     }
  1310         -
  1311         -#ifndef SQLITE4_OMIT_DEPRECATED
  1312         -  /* The sqlite4_aggregate_count() function is deprecated.  But just to make
  1313         -  ** sure it still operates correctly, verify that its count agrees with our 
  1314         -  ** internal count when using count(*) and when the total count can be
  1315         -  ** expressed as a 32-bit integer. */
  1316         -  assert( argc==1 || p==0 || p->n>0x7fffffff
  1317         -          || p->n==sqlite4_aggregate_count(context) );
  1318         -#endif
  1319   1272   }   
  1320   1273   static void countFinalize(sqlite4_context *context){
  1321   1274     CountCtx *p;
  1322   1275     p = sqlite4_aggregate_context(context, 0);
  1323   1276     sqlite4_result_int64(context, p ? p->n : 0);
  1324   1277   }
  1325   1278   
................................................................................
  1414   1367     if( pAccum ){
  1415   1368       if( pAccum->tooBig ){
  1416   1369         sqlite4_result_error_toobig(context);
  1417   1370       }else if( pAccum->mallocFailed ){
  1418   1371         sqlite4_result_error_nomem(context);
  1419   1372       }else{    
  1420   1373         sqlite4_result_text(context, sqlite4StrAccumFinish(pAccum), -1, 
  1421         -                          SQLITE4_DYNAMIC);
         1374  +                          SQLITE4_DYNAMIC, 0);
  1422   1375       }
  1423   1376     }
  1424   1377   }
  1425   1378   
  1426   1379   /*
  1427   1380   ** This routine does per-connection function registration.  Most
  1428   1381   ** of the built-in functions above are part of the global function set.
................................................................................
  1557   1510       FUNCTION(sqlite_source_id,   0, 0, 0, sourceidFunc     ),
  1558   1511       FUNCTION(sqlite_log,         2, 0, 0, errlogFunc       ),
  1559   1512   #ifndef SQLITE4_OMIT_COMPILEOPTION_DIAGS
  1560   1513       FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc  ),
  1561   1514       FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc  ),
  1562   1515   #endif /* SQLITE4_OMIT_COMPILEOPTION_DIAGS */
  1563   1516       FUNCTION(quote,              1, 0, 0, quoteFunc        ),
  1564         -    FUNCTION(last_insert_rowid,  0, 0, 0, last_insert_rowid),
  1565   1517       FUNCTION(changes,            0, 0, 0, changes          ),
  1566   1518       FUNCTION(total_changes,      0, 0, 0, total_changes    ),
  1567   1519       FUNCTION(replace,            3, 0, 0, replaceFunc      ),
  1568         -    FUNCTION(zeroblob,           1, 0, 0, zeroblobFunc     ),
  1569   1520     #ifdef SQLITE4_SOUNDEX
  1570   1521       FUNCTION(soundex,            1, 0, 0, soundexFunc      ),
  1571   1522     #endif
  1572   1523     #if 0 /*ndef SQLITE4_OMIT_LOAD_EXTENSION*/
  1573   1524       FUNCTION(load_extension,     1, 0, 0, loadExt          ),
  1574   1525       FUNCTION(load_extension,     2, 0, 0, loadExt          ),
  1575   1526     #endif

Changes to src/global.c.

   125    125     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e0..e7    ........ */
   126    126     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e8..ef    ........ */
   127    127     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* f0..f7    ........ */
   128    128     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40   /* f8..ff    ........ */
   129    129   };
   130    130   #endif
   131    131   
   132         -/*
   133         -** Default factory objects
   134         -*/
   135         -static KVFactory memFactory = {
   136         -   0,
   137         -   "temp",
   138         -   sqlite4KVStoreOpenMem,
   139         -   1
   140         -};
   141         -KVFactory sqlite4BuiltinFactory = {
   142         -   &memFactory,
   143         -   "main",
   144         -   sqlite4KVStoreOpenLsm,
   145         -   1
   146         -};
   147         -
   148         -/*
   149         -** The following singleton contains the global configuration for
   150         -** the SQLite library.
   151         -*/
   152         -struct sqlite4_env sqlite4DefaultEnv = {
   153         -   sizeof(sqlite4_env),       /* nByte */
   154         -   1,                         /* iVersion */
   155         -   SQLITE4_DEFAULT_MEMSTATUS, /* bMemstat */
   156         -   1,                         /* bCoreMutex */
   157         -   SQLITE4_THREADSAFE==1,     /* bFullMutex */
   158         -   0x7ffffffe,                /* mxStrlen */
   159         -   128,                       /* szLookaside */
   160         -   500,                       /* nLookaside */
   161         -   {0,0,0,0,0,0,0,0,0},       /* m */
   162         -   {0,0,0,0,0,0,0,0,0,0},     /* mutex */
   163         -   (void*)0,                  /* pHeap */
   164         -   0,                         /* nHeap */
   165         -   0, 0,                      /* mnHeap, mxHeap */
   166         -   0,                         /* mxParserStack */
   167         -   &sqlite4BuiltinFactory,    /* pFactory */
   168         -   sqlite4OsRandomness,       /* xRandomness */
   169         -   sqlite4OsCurrentTime,      /* xCurrentTime */
   170         -   /* All the rest should always be initialized to zero */
   171         -   0,                         /* isInit */
   172         -   0,                         /* pFactoryMutex */
   173         -   0,                         /* pPrngMutex */
   174         -   0, 0,                      /* prngX, prngY */
   175         -   0,                         /* xLog */
   176         -   0,                         /* pLogArg */
   177         -   0,                         /* bLocaltimeFault */
   178         -   0,                         /* pMemMutex */
   179         -   {0,0,0,0},                 /* nowValue[] */
   180         -   {0,0,0,0},                 /* mxValue[] */
   181         -   {0,}                       /* hashGlobalFunc */
   182         -};
   183         -
   184         -/*
   185         -** Return the default environment
   186         -*/
   187         -sqlite4_env *sqlite4_env_default(void){ return &sqlite4DefaultEnv; }
   188         -
   189    132   
   190    133   /*
   191    134   ** Constant tokens for values 0 and 1.
   192    135   */
   193    136   const Token sqlite4IntTokens[] = {
   194    137      { "0", 1 },
   195    138      { "1", 1 }

Changes to src/insert.c.

  1315   1315       if( pIdx!=pPk ){
  1316   1316         for(i=0; i<pPk->nColumn; i++){
  1317   1317           int idx = pPk->aiColumn[i];
  1318   1318           sqlite4VdbeAddOp2(v, OP_SCopy, regContent+idx, regTmp+i+pIdx->nColumn);
  1319   1319         }
  1320   1320       }
  1321   1321       sqlite4VdbeAddOp3(v, OP_MakeIdxKey, iIdx, regTmp, regKey);
  1322         -    if( pIdx==pPk && (pPk->fIndex & IDX_IntPK)!=0 ){
  1323         -      sqlite4VdbeChangeP5(v, OPFLAG_LASTROWID);
  1324         -    }
  1325   1322       VdbeComment((v, "key for %s", pIdx->zName));
  1326   1323   
  1327   1324       /* If Index.onError==OE_None, then pIdx is not a UNIQUE or PRIMARY KEY 
  1328   1325       ** index. In this case there is no need to test the index for uniqueness
  1329   1326       ** - all that is required is to populate the regKey register. Jump 
  1330   1327       ** to the next iteration of the loop if this is the case.  */
  1331   1328       onError = pIdx->onError;
................................................................................
  1800   1797       addr1 = sqlite4VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
  1801   1798     }else{
  1802   1799       addr1 = sqlite4VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
  1803   1800       assert( (pDest->tabFlags & TF_Autoincrement)==0 );
  1804   1801     }
  1805   1802     sqlite4VdbeAddOp2(v, OP_RowData, iSrc, regData);
  1806   1803     sqlite4VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid);
  1807         -  sqlite4VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
         1804  +  sqlite4VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_APPEND);
  1808   1805     sqlite4VdbeChangeP4(v, -1, pDest->zName, 0);
  1809   1806     sqlite4VdbeAddOp2(v, OP_Next, iSrc, addr1);
  1810   1807     for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
  1811   1808       for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
  1812   1809         if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
  1813   1810       }
  1814   1811       assert( pSrcIdx );

Changes to src/kvlsm.c.

   459    459   
   460    460       memset(pNew, 0, sizeof(KVLsm));
   461    461       pNew->base.pStoreVfunc = &kvlsmMethods;
   462    462       pNew->base.pEnv = pEnv;
   463    463       rc = lsm_new(0, &pNew->pDb);
   464    464       if( rc==SQLITE4_OK ){
   465    465         int i;
   466         -      int bMmap = 0;
          466  +      int bMmap = 1;
   467    467         lsm_config(pNew->pDb, LSM_CONFIG_MMAP, &bMmap);
   468    468         for(i=0; i<ArraySize(aConfig); i++){
   469    469           const char *zVal = sqlite4_uri_parameter(zName, aConfig[i].zParam);
   470    470           if( zVal ){
   471    471             int nVal = sqlite4Atoi(zVal);
   472    472             lsm_config(pNew->pDb, aConfig[i].eParam, &nVal);
   473    473           }

Changes to src/lsm.h.

    20     20   extern "C" {
    21     21   #endif
    22     22   
    23     23   /*
    24     24   ** Opaque handle types.
    25     25   */
    26     26   typedef struct lsm_compress lsm_compress;   /* Compression library functions */
           27  +typedef struct lsm_compress_factory lsm_compress_factory;
    27     28   typedef struct lsm_cursor lsm_cursor;       /* Database cursor handle */
    28     29   typedef struct lsm_db lsm_db;               /* Database connection handle */
    29     30   typedef struct lsm_env lsm_env;             /* Runtime environment */
    30     31   typedef struct lsm_file lsm_file;           /* OS file handle */
    31     32   typedef struct lsm_mutex lsm_mutex;         /* Mutex handle */
    32     33   
    33     34   /* 64-bit integer type used for file offsets. */
................................................................................
    34     35   typedef long long int lsm_i64;              /* 64-bit signed integer type */
    35     36   
    36     37   /* Candidate values for the 3rd argument to lsm_env.xLock() */
    37     38   #define LSM_LOCK_UNLOCK 0
    38     39   #define LSM_LOCK_SHARED 1
    39     40   #define LSM_LOCK_EXCL   2
    40     41   
           42  +/* Flags for lsm_env.xOpen() */
           43  +#define LSM_OPEN_READONLY 0x0001
           44  +
    41     45   /*
    42     46   ** CAPI: Database Runtime Environment
    43     47   **
    44     48   ** Run-time environment used by LSM
    45     49   **
    46     50   ** xMap(pFile, iOff, nByte, ppOut, pnOut):
    47     51   **   Memory map nByte bytes of file pFile starting at file offset iOff. If
................................................................................
    62     66   */
    63     67   struct lsm_env {
    64     68     int nByte;                 /* Size of this structure in bytes */
    65     69     int iVersion;              /* Version number of this structure (1) */
    66     70     /****** file i/o ***********************************************/
    67     71     void *pVfsCtx;
    68     72     int (*xFullpath)(lsm_env*, const char *, char *, int *);
    69         -  int (*xOpen)(lsm_env*, const char *, lsm_file **);
           73  +  int (*xOpen)(lsm_env*, const char *, int flags, lsm_file **);
    70     74     int (*xRead)(lsm_file *, lsm_i64, void *, int);
    71     75     int (*xWrite)(lsm_file *, lsm_i64, void *, int);
    72     76     int (*xTruncate)(lsm_file *, lsm_i64);
    73     77     int (*xSync)(lsm_file *);
    74     78     int (*xSectorSize)(lsm_file *);
    75     79   #if 0
    76     80     int (*xRemap)(lsm_file *, lsm_i64, void **, lsm_i64*);
................................................................................
    77     81   #endif
    78     82     int (*xMap)(lsm_file *, lsm_i64 iOff, lsm_i64 nByte, void **, lsm_i64 *);
    79     83     int (*xUnmap)(lsm_file *, void *, lsm_i64);
    80     84     int (*xFileid)(lsm_file *, void *pBuf, int *pnBuf);
    81     85     int (*xClose)(lsm_file *);
    82     86     int (*xUnlink)(lsm_env*, const char *);
    83     87     int (*xLock)(lsm_file*, int, int);
           88  +  int (*xTestLock)(lsm_file*, int, int, int);
    84     89     int (*xShmMap)(lsm_file*, int, int, void **);
    85     90     void (*xShmBarrier)(void);
    86     91     int (*xShmUnmap)(lsm_file*, int);
    87     92     /****** memory allocation ****************************************/
    88     93     void *pMemCtx;
    89     94     void *(*xMalloc)(lsm_env*, int);            /* malloc(3) function */
    90     95     void *(*xRealloc)(lsm_env*, void *, int);   /* realloc(3) function */
................................................................................
   116    121   /*
   117    122   ** CAPI: LSM Error Codes
   118    123   */
   119    124   #define LSM_OK         0
   120    125   #define LSM_ERROR      1
   121    126   #define LSM_BUSY       5
   122    127   #define LSM_NOMEM      7
          128  +#define LSM_READONLY   8
   123    129   #define LSM_IOERR     10
   124    130   #define LSM_CORRUPT   11
   125    131   #define LSM_FULL      13
   126    132   #define LSM_CANTOPEN  14
   127    133   #define LSM_PROTOCOL  15
   128    134   #define LSM_MISUSE    21
   129    135   
          136  +#define LSM_MISMATCH  50
          137  +
          138  +
          139  +#define LSM_IOERR_NOENT (LSM_IOERR | (1<<8))
          140  +
   130    141   /* 
   131    142   ** CAPI: Creating and Destroying Database Connection Handles
   132    143   **
   133    144   ** Open and close a database connection handle.
   134    145   */
   135    146   int lsm_new(lsm_env*, lsm_db **ppDb);
   136    147   int lsm_close(lsm_db *pDb);
................................................................................
   137    148   
   138    149   /* 
   139    150   ** CAPI: Connecting to a Database
   140    151   */
   141    152   int lsm_open(lsm_db *pDb, const char *zFilename);
   142    153   
   143    154   /*
   144         -** CAPI: Obtaining pointers to databases environments
          155  +** CAPI: Obtaining pointers to database environments
   145    156   **
   146    157   ** Return a pointer to the environment used by the database connection 
   147    158   ** passed as the first argument. Assuming the argument is valid, this 
   148    159   ** function always returns a valid environment pointer - it cannot fail.
   149    160   */
   150    161   lsm_env *lsm_get_env(lsm_db *pDb);
   151    162   
................................................................................
   163    174   */
   164    175   int lsm_config(lsm_db *, int, ...);
   165    176   
   166    177   /*
   167    178   ** The following values may be passed as the second argument to lsm_config().
   168    179   **
   169    180   ** LSM_CONFIG_AUTOFLUSH:
   170         -**   A read/write integer parameter. This value determines the maximum amount
   171         -**   of space (in bytes) used to accumulate writes in main-memory before 
   172         -**   they are flushed to a level 0 segment.
          181  +**   A read/write integer parameter. 
          182  +**
          183  +**   This value determines the amount of data allowed to accumulate in a
          184  +**   live in-memory tree before it is marked as old. After committing a
          185  +**   transaction, a connection checks if the size of the live in-memory tree,
          186  +**   including data structure overhead, is greater than the value of this
          187  +**   option in KB. If it is, and there is not already an old in-memory tree,
          188  +**   the live in-memory tree is marked as old.
          189  +**
          190  +**   The maximum allowable value is 1048576 (1GB). There is no minimum 
          191  +**   value. If this parameter is set to zero, then an attempt is made to
          192  +**   mark the live in-memory tree as old after each transaction is committed.
          193  +**
          194  +**   The default value is 1024 (1MB).
   173    195   **
   174    196   ** LSM_CONFIG_PAGE_SIZE:
   175    197   **   A read/write integer parameter. This parameter may only be set before
   176    198   **   lsm_open() has been called.
   177    199   **
   178    200   ** LSM_CONFIG_BLOCK_SIZE:
   179         -**   A read/write integer parameter. This parameter may only be set before
   180         -**   lsm_open() has been called.
          201  +**   A read/write integer parameter. 
   181    202   **
   182         -** LSM_CONFIG_LOG_SIZE:
   183         -**   A read/write integer parameter.
          203  +**   This parameter may only be set before lsm_open() has been called. It
          204  +**   must be set to a power of two between 64 and 65536, inclusive (block 
          205  +**   sizes between 64KB and 64MB).
          206  +**
          207  +**   If the connection creates a new database, the block size of the new
          208  +**   database is set to the value of this option in KB. After lsm_open()
          209  +**   has been called, querying this parameter returns the actual block
          210  +**   size of the opened database.
          211  +**
          212  +**   The default value is 1024 (1MB blocks).
   184    213   **
   185    214   ** LSM_CONFIG_SAFETY:
   186    215   **   A read/write integer parameter. Valid values are 0, 1 (the default) 
   187    216   **   and 2. This parameter determines how robust the database is in the
   188    217   **   face of a system crash (e.g. a power failure or operating system 
   189    218   **   crash). As follows:
   190    219   **
................................................................................
   199    228   **                 contains all successfully committed transactions.
   200    229   **
   201    230   ** LSM_CONFIG_AUTOWORK:
   202    231   **   A read/write integer parameter.
   203    232   **
   204    233   ** LSM_CONFIG_AUTOCHECKPOINT:
   205    234   **   A read/write integer parameter.
          235  +**
          236  +**   If this option is set to non-zero value N, then a checkpoint is
          237  +**   automatically attempted after each N KB of data have been written to 
          238  +**   the database file.
          239  +**
          240  +**   The amount of uncheckpointed data already written to the database file
          241  +**   is a global parameter. After performing database work (writing to the
          242  +**   database file), the process checks if the total amount of uncheckpointed 
          243  +**   data exceeds the value of this paramter. If so, a checkpoint is performed.
          244  +**   This means that this option may cause the connection to perform a 
          245  +**   checkpoint even if the current connection has itself written very little
          246  +**   data into the database file.
          247  +**
          248  +**   The default value is 2048 (checkpoint every 2MB).
   206    249   **
   207    250   ** LSM_CONFIG_MMAP:
   208    251   **   A read/write integer parameter. True to use mmap() to access the 
   209    252   **   database file. False otherwise.
   210    253   **
   211    254   ** LSM_CONFIG_USE_LOG:
   212    255   **   A read/write boolean parameter. True (the default) to use the log
................................................................................
   240    283   **
   241    284   **   This option may only be used before lsm_open() is called. Invoking it
   242    285   **   after lsm_open() has been called results in an LSM_MISUSE error.
   243    286   **
   244    287   ** LSM_CONFIG_GET_COMPRESSION:
   245    288   **   Query the compression methods used to compress and decompress database
   246    289   **   content.
          290  +**
          291  +** LSM_CONFIG_SET_COMPRESSION_FACTORY:
          292  +**   Configure a factory method to be invoked in case of an LSM_MISMATCH
          293  +**   error.
          294  +**
          295  +** LSM_CONFIG_READONLY:
          296  +**   A read/write boolean parameter. This parameter may only be set before
          297  +**   lsm_open() is called.
   247    298   */
   248         -#define LSM_CONFIG_AUTOFLUSH           1
   249         -#define LSM_CONFIG_PAGE_SIZE           2
   250         -#define LSM_CONFIG_SAFETY              3
   251         -#define LSM_CONFIG_BLOCK_SIZE          4
   252         -#define LSM_CONFIG_AUTOWORK            5
   253         -#define LSM_CONFIG_LOG_SIZE            6
   254         -#define LSM_CONFIG_MMAP                7
   255         -#define LSM_CONFIG_USE_LOG             8
   256         -#define LSM_CONFIG_AUTOMERGE           9
   257         -#define LSM_CONFIG_MAX_FREELIST       10
   258         -#define LSM_CONFIG_MULTIPLE_PROCESSES 11
   259         -#define LSM_CONFIG_AUTOCHECKPOINT     12
   260         -#define LSM_CONFIG_SET_COMPRESSION    13
   261         -#define LSM_CONFIG_GET_COMPRESSION    14
          299  +#define LSM_CONFIG_AUTOFLUSH                1
          300  +#define LSM_CONFIG_PAGE_SIZE                2
          301  +#define LSM_CONFIG_SAFETY                   3
          302  +#define LSM_CONFIG_BLOCK_SIZE               4
          303  +#define LSM_CONFIG_AUTOWORK                 5
          304  +#define LSM_CONFIG_MMAP                     7
          305  +#define LSM_CONFIG_USE_LOG                  8
          306  +#define LSM_CONFIG_AUTOMERGE                9
          307  +#define LSM_CONFIG_MAX_FREELIST            10
          308  +#define LSM_CONFIG_MULTIPLE_PROCESSES      11
          309  +#define LSM_CONFIG_AUTOCHECKPOINT          12
          310  +#define LSM_CONFIG_SET_COMPRESSION         13
          311  +#define LSM_CONFIG_GET_COMPRESSION         14
          312  +#define LSM_CONFIG_SET_COMPRESSION_FACTORY 15
          313  +#define LSM_CONFIG_READONLY                16
   262    314   
   263    315   #define LSM_SAFETY_OFF    0
   264    316   #define LSM_SAFETY_NORMAL 1
   265    317   #define LSM_SAFETY_FULL   2
   266    318   
   267    319   #define LSM_MMAP_OFF     0
   268    320   #define LSM_MMAP_FULL    1
................................................................................
   273    325   */
   274    326   struct lsm_compress {
   275    327     void *pCtx;
   276    328     unsigned int iId;
   277    329     int (*xBound)(void *, int nSrc);
   278    330     int (*xCompress)(void *, char *, int *, const char *, int);
   279    331     int (*xUncompress)(void *, char *, int *, const char *, int);
          332  +  void (*xFree)(void *pCtx);
          333  +};
          334  +
          335  +struct lsm_compress_factory {
          336  +  void *pCtx;
          337  +  int (*xFactory)(void *, lsm_db *, unsigned int);
          338  +  void (*xFree)(void *pCtx);
   280    339   };
   281    340   
          341  +#define LSM_COMPRESSION_EMPTY 0
          342  +#define LSM_COMPRESSION_NONE  1
   282    343   
   283    344   /*
   284    345   ** CAPI: Allocating and Freeing Memory
   285    346   **
   286    347   ** Invoke the memory allocation functions that belong to environment
   287    348   ** pEnv. Or the system defaults if no memory allocation functions have 
   288    349   ** been registered.
................................................................................
   386    447   **
   387    448   **   The Tcl structure returned is a list containing one element for each
   388    449   **   free block in the database. The element itself consists of two 
   389    450   **   integers - the block number and the id of the snapshot that freed it.
   390    451   **
   391    452   ** LSM_INFO_CHECKPOINT_SIZE:
   392    453   **   The third argument should be of type (int *). The location pointed to
   393         -**   by this argument is populated with the number of bytes written to the
          454  +**   by this argument is populated with the number of KB written to the
   394    455   **   database file since the most recent checkpoint.
   395    456   **
   396    457   ** LSM_INFO_TREE_SIZE:
   397    458   **   If this value is passed as the second argument to an lsm_info() call, it
   398    459   **   should be followed by two arguments of type (int *) (for a total of four
   399    460   **   arguments).
   400    461   **
................................................................................
   403    464   **   tree structures being used by older clients - this API does not provide
   404    465   **   information on them). One tree structure - the current tree - is used to
   405    466   **   accumulate new data written to the database. The other tree structure -
   406    467   **   the old tree - is a read-only tree holding older data and may be flushed 
   407    468   **   to disk at any time.
   408    469   ** 
   409    470   **   Assuming no error occurs, the location pointed to by the first of the two
   410         -**   (int *) arguments is set to the size of the old in-memory tree in bytes.
          471  +**   (int *) arguments is set to the size of the old in-memory tree in KB.
   411    472   **   The second is set to the size of the current, or live in-memory tree.
          473  +**
          474  +** LSM_INFO_COMPRESSION_ID:
          475  +**   This value should be followed by a single argument of type 
          476  +**   (unsigned int *). If successful, the location pointed to is populated 
          477  +**   with the database compression id before returning.
   412    478   */
   413    479   #define LSM_INFO_NWRITE           1
   414    480   #define LSM_INFO_NREAD            2
   415    481   #define LSM_INFO_DB_STRUCTURE     3
   416    482   #define LSM_INFO_LOG_STRUCTURE    4
   417    483   #define LSM_INFO_ARRAY_STRUCTURE  5
   418    484   #define LSM_INFO_PAGE_ASCII_DUMP  6
   419    485   #define LSM_INFO_PAGE_HEX_DUMP    7
   420    486   #define LSM_INFO_FREELIST         8
   421    487   #define LSM_INFO_ARRAY_PAGES      9
   422    488   #define LSM_INFO_CHECKPOINT_SIZE 10
   423    489   #define LSM_INFO_TREE_SIZE       11
   424         -
   425    490   #define LSM_INFO_FREELIST_SIZE   12
          491  +#define LSM_INFO_COMPRESSION_ID  13
   426    492   
   427    493   
   428    494   /* 
   429    495   ** CAPI: Opening and Closing Write Transactions
   430    496   **
   431    497   ** These functions are used to open and close transactions and nested 
   432    498   ** sub-transactions.
................................................................................
   481    547   );
   482    548   
   483    549   /*
   484    550   ** CAPI: Explicit Database Work and Checkpointing
   485    551   **
   486    552   ** This function is called by a thread to work on the database structure.
   487    553   */
   488         -int lsm_work(lsm_db *pDb, int nMerge, int nPage, int *pnWrite);
          554  +int lsm_work(lsm_db *pDb, int nMerge, int nKB, int *pnWrite);
   489    555   
   490    556   int lsm_flush(lsm_db *pDb);
   491    557   
   492    558   /*
   493    559   ** Attempt to checkpoint the current database snapshot. Return an LSM
   494    560   ** error code if an error occurs or LSM_OK otherwise.
   495    561   **
   496    562   ** If the current snapshot has already been checkpointed, calling this 
   497         -** function is a no-op. In this case if pnByte is not NULL, *pnByte is
          563  +** function is a no-op. In this case if pnKB is not NULL, *pnKB is
   498    564   ** set to 0. Or, if the current snapshot is successfully checkpointed
   499         -** by this function and pbCkpt is not NULL, *pnByte is set to the number
          565  +** by this function and pbKB is not NULL, *pnKB is set to the number
   500    566   ** of bytes written to the database file since the previous checkpoint
   501    567   ** (the same measure as returned by the LSM_INFO_CHECKPOINT_SIZE query).
   502    568   */
   503         -int lsm_checkpoint(lsm_db *pDb, int *pnByte);
          569  +int lsm_checkpoint(lsm_db *pDb, int *pnKB);
   504    570   
   505    571   /*
   506    572   ** CAPI: Opening and Closing Database Cursors
   507    573   **
   508    574   ** Open and close a database cursor.
   509    575   */
   510    576   int lsm_csr_open(lsm_db *pDb, lsm_cursor **ppCsr);

Changes to src/lsmInt.h.

    41     41   /*
    42     42   ** Default values for various data structure parameters. These may be
    43     43   ** overridden by calls to lsm_config().
    44     44   */
    45     45   #define LSM_DFLT_PAGE_SIZE          (4 * 1024)
    46     46   #define LSM_DFLT_BLOCK_SIZE         (1 * 1024 * 1024)
    47     47   #define LSM_DFLT_AUTOFLUSH          (1 * 1024 * 1024)
    48         -#define LSM_DFLT_AUTOCHECKPOINT     (2 * 1024 * 1024)
           48  +#define LSM_DFLT_AUTOCHECKPOINT     (i64)(2 * 1024 * 1024)
    49     49   #define LSM_DFLT_AUTOWORK           1
    50     50   #define LSM_DFLT_LOG_SIZE           (128*1024)
    51     51   #define LSM_DFLT_AUTOMERGE          4
    52     52   #define LSM_DFLT_SAFETY             LSM_SAFETY_NORMAL
    53     53   #define LSM_DFLT_MMAP               (LSM_IS_64_BIT ? LSM_MMAP_FULL : 0)
    54     54   #define LSM_DFLT_MULTIPLE_PROCESSES 1
    55     55   #define LSM_DFLT_USE_LOG            1
................................................................................
   110    110   
   111    111   #ifdef LSM_DEBUG
   112    112   int lsmErrorBkpt(int);
   113    113   #else
   114    114   # define lsmErrorBkpt(x) (x)
   115    115   #endif
   116    116   
   117         -#define LSM_IOERR_BKPT   lsmErrorBkpt(LSM_IOERR)
   118         -#define LSM_NOMEM_BKPT   lsmErrorBkpt(LSM_NOMEM)
   119         -#define LSM_CORRUPT_BKPT lsmErrorBkpt(LSM_CORRUPT)
   120         -#define LSM_MISUSE_BKPT  lsmErrorBkpt(LSM_MISUSE)
          117  +#define LSM_PROTOCOL_BKPT lsmErrorBkpt(LSM_PROTOCOL)
          118  +#define LSM_IOERR_BKPT    lsmErrorBkpt(LSM_IOERR)
          119  +#define LSM_NOMEM_BKPT    lsmErrorBkpt(LSM_NOMEM)
          120  +#define LSM_CORRUPT_BKPT  lsmErrorBkpt(LSM_CORRUPT)
          121  +#define LSM_MISUSE_BKPT   lsmErrorBkpt(LSM_MISUSE)
   121    122   
   122    123   #define unused_parameter(x) (void)(x)
   123    124   #define array_size(x) (sizeof(x)/sizeof(x[0]))
   124    125   
   125    126   
   126    127   /* The size of each shared-memory chunk */
   127    128   #define LSM_SHM_CHUNK_SIZE (32*1024)
................................................................................
   128    129   
   129    130   /* The number of bytes reserved at the start of each shm chunk for MM. */
   130    131   #define LSM_SHM_CHUNK_HDR  (sizeof(ShmChunk))
   131    132   
   132    133   /* The number of available read locks. */
   133    134   #define LSM_LOCK_NREADER   6
   134    135   
   135         -/* Lock definitions */
   136         -#define LSM_LOCK_DMS1         1
   137         -#define LSM_LOCK_DMS2         2
   138         -#define LSM_LOCK_WRITER       3
   139         -#define LSM_LOCK_WORKER       4
   140         -#define LSM_LOCK_CHECKPOINTER 5
   141         -#define LSM_LOCK_READER(i)    ((i) + LSM_LOCK_CHECKPOINTER + 1)
          136  +/* The number of available read-write client locks. */
          137  +#define LSM_LOCK_NRWCLIENT   16
          138  +
          139  +/* Lock definitions. 
          140  +*/
          141  +#define LSM_LOCK_DMS1         1   /* Serialize connect/disconnect ops */
          142  +#define LSM_LOCK_DMS2         2   /* Read-write connections */
          143  +#define LSM_LOCK_DMS3         3   /* Read-only connections */
          144  +#define LSM_LOCK_WRITER       4
          145  +#define LSM_LOCK_WORKER       5
          146  +#define LSM_LOCK_CHECKPOINTER 6
          147  +#define LSM_LOCK_ROTRANS      7
          148  +#define LSM_LOCK_READER(i)    ((i) + LSM_LOCK_ROTRANS + 1)
          149  +#define LSM_LOCK_RWCLIENT(i)  ((i) + LSM_LOCK_READER(LSM_LOCK_NREADER))
   142    150   
   143    151   /*
   144    152   ** Hard limit on the number of free-list entries that may be stored in 
   145    153   ** a checkpoint (the remainder are stored as a system record in the LSM).
   146    154   ** See also LSM_CONFIG_MAX_FREELIST.
   147    155   */
   148    156   #define LSM_MAX_FREELIST_ENTRIES 24
................................................................................
   158    166   */
   159    167   #define LSM_START_DELETE 0x01     /* Start of open-ended delete range */
   160    168   #define LSM_END_DELETE   0x02     /* End of open-ended delete range */
   161    169   #define LSM_POINT_DELETE 0x04     /* Delete this key */
   162    170   #define LSM_INSERT       0x08     /* Insert this key and value */
   163    171   #define LSM_SEPARATOR    0x10     /* True if entry is separator key only */
   164    172   #define LSM_SYSTEMKEY    0x20     /* True if entry is a system key (FREELIST) */
          173  +
          174  +#define LSM_CONTIGUOUS   0x40     /* Used in lsm_tree.c */
   165    175   
   166    176   /*
   167    177   ** A string that can grow by appending.
   168    178   */
   169    179   struct LsmString {
   170    180     lsm_env *pEnv;              /* Run-time environment */
   171    181     int n;                      /* Size of string.  -1 indicates error */
................................................................................
   280    290   
   281    291   /*
   282    292   ** Database handle structure.
   283    293   **
   284    294   ** mLock:
   285    295   **   A bitmask representing the locks currently held by the connection.
   286    296   **   An LSM database supports N distinct locks, where N is some number less
   287         -**   than or equal to 16. Locks are numbered starting from 1 (see the 
          297  +**   than or equal to 32. Locks are numbered starting from 1 (see the 
   288    298   **   definitions for LSM_LOCK_WRITER and co.).
   289    299   **
   290         -**   The least significant 16-bits in mLock represent EXCLUSIVE locks. The
          300  +**   The least significant 32-bits in mLock represent EXCLUSIVE locks. The
   291    301   **   most significant are SHARED locks. So, if a connection holds a SHARED
   292    302   **   lock on lock region iLock, then the following is true:
   293    303   **
   294         -**       (mLock & ((iLock+16-1) << 1))
          304  +**       (mLock & ((iLock+32-1) << 1))
   295    305   **
   296    306   **   Or for an EXCLUSIVE lock:
   297    307   **
   298    308   **       (mLock & ((iLock-1) << 1))
          309  +** 
          310  +** pCsr:
          311  +**   Points to the head of a linked list that contains all currently open
          312  +**   cursors. Once this list becomes empty, the user has no outstanding
          313  +**   cursors and the database handle can be successfully closed.
          314  +**
          315  +** pCsrCache:
          316  +**   This list contains cursor objects that have been closed using
          317  +**   lsm_csr_close(). Each time a cursor is closed, it is shifted from 
          318  +**   the pCsr list to this list. When a new cursor is opened, this list
          319  +**   is inspected to see if there exists a cursor object that can be
          320  +**   reused. This is an optimization only.
   299    321   */
   300    322   struct lsm_db {
   301    323   
   302    324     /* Database handle configuration */
   303    325     lsm_env *pEnv;                            /* runtime environment */
   304    326     int (*xCmp)(void *, int, void *, int);    /* Compare function */
   305    327   
   306    328     /* Values configured by calls to lsm_config */
   307    329     int eSafety;                    /* LSM_SAFETY_OFF, NORMAL or FULL */
   308    330     int bAutowork;                  /* Configured by LSM_CONFIG_AUTOWORK */
   309    331     int nTreeLimit;                 /* Configured by LSM_CONFIG_AUTOFLUSH */
   310    332     int nMerge;                     /* Configured by LSM_CONFIG_AUTOMERGE */
   311         -  int nLogSz;                     /* Configured by LSM_CONFIG_LOG_SIZE */
   312    333     int bUseLog;                    /* Configured by LSM_CONFIG_USE_LOG */
   313    334     int nDfltPgsz;                  /* Configured by LSM_CONFIG_PAGE_SIZE */
   314    335     int nDfltBlksz;                 /* Configured by LSM_CONFIG_BLOCK_SIZE */
   315    336     int nMaxFreelist;               /* Configured by LSM_CONFIG_MAX_FREELIST */
   316    337     int eMmap;                      /* Configured by LSM_CONFIG_MMAP */
   317         -  int nAutockpt;                  /* Configured by LSM_CONFIG_AUTOCHECKPOINT */
          338  +  i64 nAutockpt;                  /* Configured by LSM_CONFIG_AUTOCHECKPOINT */
   318    339     int bMultiProc;                 /* Configured by L_C_MULTIPLE_PROCESSES */
          340  +  int bReadonly;                  /* Configured by LSM_CONFIG_READONLY */
   319    341     lsm_compress compress;          /* Compression callbacks */
          342  +  lsm_compress_factory factory;   /* Compression callback factory */
   320    343   
   321    344     /* Sub-system handles */
   322    345     FileSystem *pFS;                /* On-disk portion of database */
   323    346     Database *pDatabase;            /* Database shared data */
   324    347   
          348  +  int iRwclient;                  /* Read-write client lock held (-1 == none) */
          349  +
   325    350     /* Client transaction context */
   326    351     Snapshot *pClient;              /* Client snapshot */
   327    352     int iReader;                    /* Read lock held (-1 == unlocked) */
          353  +  int bRoTrans;                   /* True if a read-only db trans is open */
   328    354     MultiCursor *pCsr;              /* List of all open cursors */
   329    355     LogWriter *pLogWriter;          /* Context for writing to the log file */
   330    356     int nTransOpen;                 /* Number of opened write transactions */
   331    357     int nTransAlloc;                /* Allocated size of aTrans[] array */
   332    358     TransMark *aTrans;              /* Array of marks for transaction rollback */
   333    359     IntArray rollback;              /* List of tree-nodes to roll back */
          360  +  int bDiscardOld;                /* True if lsmTreeDiscardOld() was called */
          361  +
          362  +  MultiCursor *pCsrCache;         /* List of all closed cursors */
   334    363   
   335    364     /* Worker context */
   336    365     Snapshot *pWorker;              /* Worker snapshot (or NULL) */
   337    366     Freelist *pFreelist;            /* See sortedNewToplevel() */
   338    367     int bUseFreelist;               /* True to use pFreelist */
   339    368     int bIncrMerge;                 /* True if currently doing a merge */
          369  +
          370  +  int bInFactory;                 /* True if within factory.xFactory() */
   340    371   
   341    372     /* Debugging message callback */
   342    373     void (*xLog)(void *, int, const char *);
   343    374     void *pLogCtx;
   344    375   
   345    376     /* Work done notification callback */
   346    377     void (*xWork)(lsm_db *, void *);
   347    378     void *pWorkCtx;
   348    379   
   349         -  u32 mLock;                      /* Mask of current locks. See lsmShmLock(). */
          380  +  u64 mLock;                      /* Mask of current locks. See lsmShmLock(). */
   350    381     lsm_db *pNext;                  /* Next connection to same database */
   351    382   
   352    383     int nShm;                       /* Size of apShm[] array */
   353    384     void **apShm;                   /* Shared memory chunks */
   354    385     ShmHeader *pShmhdr;             /* Live shared-memory header */
   355    386     TreeHeader treehdr;             /* Local copy of tree-header */
   356    387     u32 aSnapshot[LSM_META_PAGE_SIZE / sizeof(u32)];
................................................................................
   523    554   /*
   524    555   ** A snapshot of a database. A snapshot contains all the information required
   525    556   ** to read or write a database file on disk. See the description of struct
   526    557   ** Database below for futher details.
   527    558   */
   528    559   struct Snapshot {
   529    560     Database *pDatabase;            /* Database this snapshot belongs to */
          561  +  u32 iCmpId;                     /* Id of compression scheme */
   530    562     Level *pLevel;                  /* Pointer to level 0 of snapshot (or NULL) */
   531    563     i64 iId;                        /* Snapshot id */
   532    564     i64 iLogOff;                    /* Log file offset */
   533    565     Redirect redirect;              /* Block redirection array */
   534    566   
   535    567     /* Used by worker snapshots only */
   536    568     int nBlock;                     /* Number of blocks in database file */
................................................................................
   568    600   
   569    601   int lsmCheckpointSaveWorker(lsm_db *pDb, int);
   570    602   int lsmDatabaseFull(lsm_db *pDb);
   571    603   int lsmCheckpointSynced(lsm_db *pDb, i64 *piId, i64 *piLog, u32 *pnWrite);
   572    604   
   573    605   int lsmCheckpointSize(lsm_db *db, int *pnByte);
   574    606   
          607  +int lsmInfoCompressionId(lsm_db *db, u32 *piCmpId);
          608  +
   575    609   /* 
   576    610   ** Functions from file "lsm_tree.c".
   577    611   */
   578    612   int lsmTreeNew(lsm_env *, int (*)(void *, int, void *, int), Tree **ppTree);
   579    613   void lsmTreeRelease(lsm_env *, Tree *);
   580    614   int lsmTreeInit(lsm_db *);
   581    615   int lsmTreeRepair(lsm_db *);
................................................................................
   586    620   
   587    621   int lsmTreeSize(lsm_db *);
   588    622   int lsmTreeEndTransaction(lsm_db *pDb, int bCommit);
   589    623   int lsmTreeLoadHeader(lsm_db *pDb, int *);
   590    624   int lsmTreeLoadHeaderOk(lsm_db *, int);
   591    625   
   592    626   int lsmTreeInsert(lsm_db *pDb, void *pKey, int nKey, void *pVal, int nVal);
          627  +int lsmTreeDelete(lsm_db *db, void *pKey1, int nKey1, void *pKey2, int nKey2);
   593    628   void lsmTreeRollback(lsm_db *pDb, TreeMark *pMark);
   594    629   void lsmTreeMark(lsm_db *pDb, TreeMark *pMark);
   595    630   
   596    631   int lsmTreeCursorNew(lsm_db *pDb, int, TreeCursor **);
   597    632   void lsmTreeCursorDestroy(TreeCursor *);
   598    633   
   599    634   int lsmTreeCursorSeek(TreeCursor *pCsr, void *pKey, int nKey, int *pRes);
................................................................................
   638    673   int lsmMutexHeld(lsm_env *, lsm_mutex *);
   639    674   int lsmMutexNotHeld(lsm_env *, lsm_mutex *);
   640    675   #endif
   641    676   
   642    677   /**************************************************************************
   643    678   ** Start of functions from "lsm_file.c".
   644    679   */
   645         -int lsmFsOpen(lsm_db *, const char *);
          680  +int lsmFsOpen(lsm_db *, const char *, int);
          681  +int lsmFsOpenLog(lsm_db *, int *);
          682  +void lsmFsCloseLog(lsm_db *);
   646    683   void lsmFsClose(FileSystem *);
          684  +
          685  +int lsmFsConfigure(lsm_db *db);
   647    686   
   648    687   int lsmFsBlockSize(FileSystem *);
   649    688   void lsmFsSetBlockSize(FileSystem *, int);
   650    689   
   651    690   int lsmFsPageSize(FileSystem *);
   652    691   void lsmFsSetPageSize(FileSystem *, int);
   653    692   
................................................................................
   710    749   void lsmFsFlushWaiting(FileSystem *, int *);
   711    750   
   712    751   /* Used by lsm_info(ARRAY_STRUCTURE) and lsm_config(MMAP) */
   713    752   int lsmInfoArrayStructure(lsm_db *pDb, int bBlock, Pgno iFirst, char **pzOut);
   714    753   int lsmInfoArrayPages(lsm_db *pDb, Pgno iFirst, char **pzOut);
   715    754   int lsmConfigMmap(lsm_db *pDb, int *piParam);
   716    755   
   717         -int lsmEnvOpen(lsm_env *, const char *, lsm_file **);
          756  +int lsmEnvOpen(lsm_env *, const char *, int, lsm_file **);
   718    757   int lsmEnvClose(lsm_env *pEnv, lsm_file *pFile);
   719    758   int lsmEnvLock(lsm_env *pEnv, lsm_file *pFile, int iLock, int eLock);
          759  +int lsmEnvTestLock(lsm_env *pEnv, lsm_file *pFile, int iLock, int nLock, int);
   720    760   
   721    761   int lsmEnvShmMap(lsm_env *, lsm_file *, int, int, void **); 
   722    762   void lsmEnvShmBarrier(lsm_env *);
   723    763   void lsmEnvShmUnmap(lsm_env *, lsm_file *, int);
   724    764   
   725    765   void lsmEnvSleep(lsm_env *, int);
   726    766   
................................................................................
   756    796   int lsmSortedLoadFreelist(lsm_db *pDb, void **, int *);
   757    797   
   758    798   void *lsmSortedSplitKey(Level *pLevel, int *pnByte);
   759    799   
   760    800   void lsmSortedSaveTreeCursors(lsm_db *);
   761    801   
   762    802   int lsmMCursorNew(lsm_db *, MultiCursor **);
   763         -void lsmMCursorClose(MultiCursor *);
          803  +void lsmMCursorClose(MultiCursor *, int);
   764    804   int lsmMCursorSeek(MultiCursor *, int, void *, int , int);
   765    805   int lsmMCursorFirst(MultiCursor *);
   766    806   int lsmMCursorPrev(MultiCursor *);
   767    807   int lsmMCursorLast(MultiCursor *);
   768    808   int lsmMCursorValid(MultiCursor *);
   769    809   int lsmMCursorNext(MultiCursor *);
   770    810   int lsmMCursorKey(MultiCursor *, void **, int *);
   771    811   int lsmMCursorValue(MultiCursor *, void **, int *);
   772    812   int lsmMCursorType(MultiCursor *, int *);
   773    813   lsm_db *lsmMCursorDb(MultiCursor *);
          814  +void lsmMCursorFreeCache(lsm_db *);
   774    815   
   775    816   int lsmSaveCursors(lsm_db *pDb);
   776    817   int lsmRestoreCursors(lsm_db *pDb);
   777    818   
   778    819   void lsmSortedDumpStructure(lsm_db *pDb, Snapshot *, int, int, const char *);
   779    820   void lsmFsDumpBlocklists(lsm_db *);
   780    821   
................................................................................
   823    864   int lsmDbDatabaseConnect(lsm_db*, const char *);
   824    865   void lsmDbDatabaseRelease(lsm_db *);
   825    866   
   826    867   int lsmBeginReadTrans(lsm_db *);
   827    868   int lsmBeginWriteTrans(lsm_db *);
   828    869   int lsmBeginFlush(lsm_db *);
   829    870   
          871  +int lsmDetectRoTrans(lsm_db *db, int *);
          872  +
   830    873   int lsmBeginWork(lsm_db *);
   831    874   void lsmFinishWork(lsm_db *, int, int *);
   832    875   
   833    876   int lsmFinishRecovery(lsm_db *);
   834    877   void lsmFinishReadTrans(lsm_db *);
   835    878   int lsmFinishWriteTrans(lsm_db *, int);
   836    879   int lsmFinishFlush(lsm_db *, int);
................................................................................
   869    912   /* Candidate values for the 3rd argument to lsmShmLock() */
   870    913   #define LSM_LOCK_UNLOCK 0
   871    914   #define LSM_LOCK_SHARED 1
   872    915   #define LSM_LOCK_EXCL   2
   873    916   
   874    917   int lsmShmCacheChunks(lsm_db *db, int nChunk);
   875    918   int lsmShmLock(lsm_db *db, int iLock, int eOp, int bBlock);
          919  +int lsmShmTestLock(lsm_db *db, int iLock, int nLock, int eOp);
   876    920   void lsmShmBarrier(lsm_db *db);
   877    921   
   878    922   #ifdef LSM_DEBUG
   879    923   void lsmShmHasLock(lsm_db *db, int iLock, int eOp);
   880    924   #else
   881    925   # define lsmShmHasLock(x,y,z)
   882    926   #endif
   883    927   
   884    928   int lsmReadlock(lsm_db *, i64 iLsm, u32 iShmMin, u32 iShmMax);
   885         -int lsmReleaseReadlock(lsm_db *);
   886    929   
   887    930   int lsmLsmInUse(lsm_db *db, i64 iLsmId, int *pbInUse);
   888    931   int lsmTreeInUse(lsm_db *db, u32 iLsmId, int *pbInUse);
   889    932   int lsmFreelistAppend(lsm_env *pEnv, Freelist *p, int iBlk, i64 iId);
   890    933   
   891    934   int lsmDbMultiProc(lsm_db *);
   892    935   void lsmDbDeferredClose(lsm_db *, lsm_file *, LsmFile *);
   893    936   LsmFile *lsmDbRecycleFd(lsm_db *);
   894    937   
   895    938   int lsmWalkFreelist(lsm_db *, int, int (*)(void *, int, i64), void *);
          939  +
          940  +int lsmCheckCompressionId(lsm_db *, u32);
   896    941   
   897    942   
   898    943   /**************************************************************************
   899    944   ** functions in lsm_str.c
   900    945   */
   901    946   void lsmStringInit(LsmString*, lsm_env *pEnv);
   902    947   int lsmStringExtend(LsmString*, int);

Changes to src/lsm_ckpt.c.

    28     28   **
    29     29   **   Checkpoint header (see the CKPT_HDR_XXX #defines):
    30     30   **
    31     31   **     1. The checkpoint id MSW.
    32     32   **     2. The checkpoint id LSW.
    33     33   **     3. The number of integer values in the entire checkpoint, including 
    34     34   **        the two checksum values.
    35         -**     4. The total number of blocks in the database.
    36         -**     5. The block size.
    37         -**     6. The number of levels.
    38         -**     7. The nominal database page size.
    39         -**     8. The number of pages (in total) written to the database file.
           35  +**     4. The compression scheme id.
           36  +**     5. The total number of blocks in the database.
           37  +**     6. The block size.
           38  +**     7. The number of levels.
           39  +**     8. The nominal database page size.
           40  +**     9. The number of pages (in total) written to the database file.
    40     41   **
    41     42   **   Log pointer:
    42     43   **
    43     44   **     1. The log offset MSW.
    44     45   **     2. The log offset LSW.
    45     46   **     3. Log checksum 0.
    46     47   **     4. Log checksum 1.
           48  +**
           49  +**     Note that the "log offset" is not the literal byte offset. Instead,
           50  +**     it is the byte offset multiplied by 2, with least significant bit
           51  +**     toggled each time the log pointer value is changed. This is to make
           52  +**     sure that this field changes each time the log pointer is updated,
           53  +**     even if the log file itself is disabled. See lsmTreeMakeOld().
    47     54   **
    48     55   **     See ckptExportLog() and ckptImportLog().
    49     56   **
    50     57   **   Append points:
    51     58   **
    52     59   **     8 integers (4 * 64-bit page numbers). See ckptExportAppendlist().
    53     60   **
................................................................................
   170    177    + (((x)&0x00FF0000)>>8)  + (((x)&0xFF000000)>>24) \
   171    178   )
   172    179   
   173    180   static const int one = 1;
   174    181   #define LSM_LITTLE_ENDIAN (*(u8 *)(&one))
   175    182   
   176    183   /* Sizes, in integers, of various parts of the checkpoint. */
   177         -#define CKPT_HDR_SIZE         8
          184  +#define CKPT_HDR_SIZE         9
   178    185   #define CKPT_LOGPTR_SIZE      4
   179    186   #define CKPT_APPENDLIST_SIZE  (LSM_APPLIST_SZ * 2)
   180    187   
   181    188   /* A #define to describe each integer in the checkpoint header. */
   182    189   #define CKPT_HDR_ID_MSW   0
   183    190   #define CKPT_HDR_ID_LSW   1
   184    191   #define CKPT_HDR_NCKPT    2
   185         -#define CKPT_HDR_NBLOCK   3
   186         -#define CKPT_HDR_BLKSZ    4
   187         -#define CKPT_HDR_NLEVEL   5
   188         -#define CKPT_HDR_PGSZ     6
   189         -#define CKPT_HDR_NWRITE   7
          192  +#define CKPT_HDR_CMPID    3
          193  +#define CKPT_HDR_NBLOCK   4
          194  +#define CKPT_HDR_BLKSZ    5
          195  +#define CKPT_HDR_NLEVEL   6
          196  +#define CKPT_HDR_PGSZ     7
          197  +#define CKPT_HDR_NWRITE   8
   190    198   
   191         -#define CKPT_HDR_LO_MSW     8
   192         -#define CKPT_HDR_LO_LSW     9
   193         -#define CKPT_HDR_LO_CKSUM1 10
   194         -#define CKPT_HDR_LO_CKSUM2 11
          199  +#define CKPT_HDR_LO_MSW     9
          200  +#define CKPT_HDR_LO_LSW    10
          201  +#define CKPT_HDR_LO_CKSUM1 11
          202  +#define CKPT_HDR_LO_CKSUM2 12
   195    203   
   196    204   typedef struct CkptBuffer CkptBuffer;
   197    205   
   198    206   /*
   199    207   ** Dynamic buffer used to accumulate data for a checkpoint.
   200    208   */
   201    209   struct CkptBuffer {
................................................................................
   445    453         ckptSetValue(&ckpt, iOut++, (p->iId >> 32) & 0xFFFFFFFF, &rc);
   446    454         ckptSetValue(&ckpt, iOut++, p->iId & 0xFFFFFFFF, &rc);
   447    455       }
   448    456     }
   449    457   
   450    458     /* Write the checkpoint header */
   451    459     assert( iId>=0 );
          460  +  assert( pSnap->iCmpId==pDb->compress.iId
          461  +       || pSnap->iCmpId==LSM_COMPRESSION_EMPTY 
          462  +  );
   452    463     ckptSetValue(&ckpt, CKPT_HDR_ID_MSW, (u32)(iId>>32), &rc);
   453    464     ckptSetValue(&ckpt, CKPT_HDR_ID_LSW, (u32)(iId&0xFFFFFFFF), &rc);
   454    465     ckptSetValue(&ckpt, CKPT_HDR_NCKPT, iOut+2, &rc);
          466  +  ckptSetValue(&ckpt, CKPT_HDR_CMPID, pDb->compress.iId, &rc);
   455    467     ckptSetValue(&ckpt, CKPT_HDR_NBLOCK, pSnap->nBlock, &rc);
   456    468     ckptSetValue(&ckpt, CKPT_HDR_BLKSZ, lsmFsBlockSize(pFS), &rc);
   457    469     ckptSetValue(&ckpt, CKPT_HDR_NLEVEL, nLevel, &rc);
   458    470     ckptSetValue(&ckpt, CKPT_HDR_PGSZ, lsmFsPageSize(pFS), &rc);
   459    471     ckptSetValue(&ckpt, CKPT_HDR_NWRITE, pSnap->nWrite, &rc);
   460    472   
   461    473     if( bCksum ){
................................................................................
   757    769   
   758    770   /*
   759    771   ** Initialize the shared-memory header with an empty snapshot. This function
   760    772   ** is called when no valid snapshot can be found in the database header.
   761    773   */
   762    774   static void ckptLoadEmpty(lsm_db *pDb){
   763    775     u32 aCkpt[] = {
   764         -    0,                  /* CKPT_HDR_ID_MSW */
   765         -    10,                 /* CKPT_HDR_ID_LSW */
   766         -    0,                  /* CKPT_HDR_NCKPT */
   767         -    0,                  /* CKPT_HDR_NBLOCK */
   768         -    0,                  /* CKPT_HDR_BLKSZ */
   769         -    0,                  /* CKPT_HDR_NLEVEL */
   770         -    0,                  /* CKPT_HDR_PGSZ */
   771         -    0,                  /* CKPT_HDR_OVFL */
   772         -    0,                  /* CKPT_HDR_NWRITE */
   773         -    0, 0, 1234, 5678,   /* The log pointer and initial checksum */
   774         -    0,0,0,0, 0,0,0,0,   /* The append list */
   775         -    0,                  /* The free block list */
   776         -    0, 0                /* Space for checksum values */
          776  +    0,                       /* CKPT_HDR_ID_MSW */
          777  +    10,                      /* CKPT_HDR_ID_LSW */
          778  +    0,                       /* CKPT_HDR_NCKPT */
          779  +    LSM_COMPRESSION_EMPTY,   /* CKPT_HDR_CMPID */
          780  +    0,                       /* CKPT_HDR_NBLOCK */
          781  +    0,                       /* CKPT_HDR_BLKSZ */
          782  +    0,                       /* CKPT_HDR_NLEVEL */
          783  +    0,                       /* CKPT_HDR_PGSZ */
          784  +    0,                       /* CKPT_HDR_OVFL */
          785  +    0,                       /* CKPT_HDR_NWRITE */
          786  +    0, 0, 1234, 5678,        /* The log pointer and initial checksum */
          787  +    0,0,0,0, 0,0,0,0,        /* The append list */
          788  +    0,                       /* The free block list */
          789  +    0, 0                     /* Space for checksum values */
   777    790     };
   778    791     u32 nCkpt = array_size(aCkpt);
   779    792     ShmHeader *pShm = pDb->pShmhdr;
   780    793   
   781    794     aCkpt[CKPT_HDR_NCKPT] = nCkpt;
   782    795     aCkpt[CKPT_HDR_BLKSZ] = pDb->nDfltBlksz;
   783    796     aCkpt[CKPT_HDR_PGSZ] = pDb->nDfltPgsz;
................................................................................
   872    885           if( piRead ) *piRead = 2;
   873    886           return LSM_OK;
   874    887         }
   875    888       }
   876    889   
   877    890       lsmShmBarrier(pDb);
   878    891     }
   879         -  return LSM_PROTOCOL;
          892  +  return LSM_PROTOCOL_BKPT;
          893  +}
          894  +
          895  +int lsmInfoCompressionId(lsm_db *db, u32 *piCmpId){
          896  +  int rc;
          897  +
          898  +  assert( db->pClient==0 && db->pWorker==0 );
          899  +  rc = lsmCheckpointLoad(db, 0);
          900  +  if( rc==LSM_OK ){
          901  +    *piCmpId = db->aSnapshot[CKPT_HDR_CMPID];
          902  +  }
          903  +
          904  +  return rc;
   880    905   }
   881    906   
   882    907   int lsmCheckpointLoadOk(lsm_db *pDb, int iSnap){
   883    908     u32 *aShm;
   884    909     assert( iSnap==1 || iSnap==2 );
   885    910     aShm = (iSnap==1) ? pDb->pShmhdr->aSnap1 : pDb->pShmhdr->aSnap2;
   886    911     return (lsmCheckpointId(pDb->aSnapshot, 0)==lsmCheckpointId(aShm, 0) );
................................................................................
   899    924     ShmHeader *pShm = pDb->pShmhdr;
   900    925     int nInt1;
   901    926     int nInt2;
   902    927   
   903    928     /* Must be holding the WORKER lock to do this. Or DMS2. */
   904    929     assert( 
   905    930         lsmShmAssertLock(pDb, LSM_LOCK_WORKER, LSM_LOCK_EXCL) 
   906         -   || lsmShmAssertLock(pDb, LSM_LOCK_DMS2, LSM_LOCK_EXCL) 
          931  +   || lsmShmAssertLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_EXCL) 
   907    932     );
   908    933   
   909    934     /* Check that the two snapshots match. If not, repair them. */
   910    935     nInt1 = pShm->aSnap1[CKPT_HDR_NCKPT];
   911    936     nInt2 = pShm->aSnap2[CKPT_HDR_NCKPT];
   912    937     if( nInt1!=nInt2 || memcmp(pShm->aSnap1, pShm->aSnap2, nInt2*sizeof(u32)) ){
   913    938       if( ckptChecksumOk(pShm->aSnap1) ){
   914    939         memcpy(pShm->aSnap2, pShm->aSnap1, sizeof(u32)*nInt1);
   915    940       }else if( ckptChecksumOk(pShm->aSnap2) ){
   916    941         memcpy(pShm->aSnap1, pShm->aSnap2, sizeof(u32)*nInt2);
   917    942       }else{
   918         -      return LSM_PROTOCOL;
          943  +      return LSM_PROTOCOL_BKPT;
   919    944       }
   920    945     }
   921    946   
   922    947     rc = lsmCheckpointDeserialize(pDb, 1, pShm->aSnap1, &pDb->pWorker);
   923    948     if( pDb->pWorker ) pDb->pWorker->pDatabase = pDb->pDatabase;
          949  +
          950  +  if( rc==LSM_OK ){
          951  +    rc = lsmCheckCompressionId(pDb, pDb->pWorker->iCmpId);
          952  +  }
   924    953   
   925    954   #if 0
   926    955     assert( rc!=LSM_OK || lsmFsIntegrityCheck(pDb) );
   927    956   #endif
   928    957     return rc;
   929    958   }
   930    959   
................................................................................
   946    975       int iIn = CKPT_HDR_SIZE + CKPT_APPENDLIST_SIZE + CKPT_LOGPTR_SIZE;
   947    976   
   948    977       pNew->iId = lsmCheckpointId(aCkpt, 0);
   949    978       pNew->nBlock = aCkpt[CKPT_HDR_NBLOCK];
   950    979       pNew->nWrite = aCkpt[CKPT_HDR_NWRITE];
   951    980       rc = ckptLoadLevels(pDb, aCkpt, &iIn, nLevel, &pNew->pLevel);
   952    981       pNew->iLogOff = lsmCheckpointLogOffset(aCkpt);
          982  +    pNew->iCmpId = aCkpt[CKPT_HDR_CMPID];
   953    983   
   954    984       /* Make a copy of the append-list */
   955    985       for(i=0; i<LSM_APPLIST_SZ; i++){
   956    986         u32 *a = &aCkpt[CKPT_HDR_SIZE + CKPT_LOGPTR_SIZE + i*2];
   957    987         pNew->aiAppend[i] = ckptRead64(a);
   958    988       }
   959    989   
................................................................................
  1095   1125         if( nCkpt<(LSM_META_PAGE_SIZE/sizeof(u32)) ){
  1096   1126           u32 *aCopy = lsmMallocRc(pDb->pEnv, sizeof(u32) * nCkpt, &rc);
  1097   1127           if( aCopy ){
  1098   1128             memcpy(aCopy, aData, nCkpt*sizeof(u32));
  1099   1129             ckptChangeEndianness(aCopy, nCkpt);
  1100   1130             if( ckptChecksumOk(aCopy) ){
  1101   1131               if( piId ) *piId = lsmCheckpointId(aCopy, 0);
  1102         -            if( piLog ) *piLog = lsmCheckpointLogOffset(aCopy);
         1132  +            if( piLog ) *piLog = (lsmCheckpointLogOffset(aCopy) >> 1);
  1103   1133               if( pnWrite ) *pnWrite = aCopy[CKPT_HDR_NWRITE];
  1104   1134             }
  1105   1135             lsmFree(pDb->pEnv, aCopy);
  1106   1136           }
  1107   1137         }
  1108   1138         lsmFsMetaPageRelease(pPg);
  1109   1139       }
................................................................................
  1155   1185   
  1156   1186   int lsmCheckpointBlksz(u32 *aCkpt){ return (int)aCkpt[CKPT_HDR_BLKSZ]; }
  1157   1187   
  1158   1188   void lsmCheckpointLogoffset(
  1159   1189     u32 *aCkpt,
  1160   1190     DbLog *pLog
  1161   1191   ){ 
  1162         -  u32 iOffMSB = aCkpt[CKPT_HDR_LO_MSW];
  1163         -  u32 iOffLSB = aCkpt[CKPT_HDR_LO_LSW];
  1164         -  pLog->aRegion[2].iStart = (((i64)iOffMSB) << 32) + ((i64)iOffLSB);
         1192  +  pLog->aRegion[2].iStart = (lsmCheckpointLogOffset(aCkpt) >> 1);
         1193  +
  1165   1194     pLog->cksum0 = aCkpt[CKPT_HDR_LO_CKSUM1];
  1166   1195     pLog->cksum1 = aCkpt[CKPT_HDR_LO_CKSUM2];
  1167   1196     pLog->iSnapshotId = lsmCheckpointId(aCkpt, 0);
  1168   1197   }
  1169   1198   
  1170   1199   void lsmCheckpointZeroLogoffset(lsm_db *pDb){
  1171   1200     u32 nCkpt;
................................................................................
  1182   1211         &pDb->aSnapshot[nCkpt-2], &pDb->aSnapshot[nCkpt-1]
  1183   1212     );
  1184   1213   
  1185   1214     memcpy(pDb->pShmhdr->aSnap1, pDb->aSnapshot, nCkpt*sizeof(u32));
  1186   1215     memcpy(pDb->pShmhdr->aSnap2, pDb->aSnapshot, nCkpt*sizeof(u32));
  1187   1216   }
  1188   1217   
  1189         -int lsmCheckpointSize(lsm_db *db, int *pnByte){
         1218  +/*
         1219  +** Set the output variable to the number of KB of data written into the
         1220  +** database file since the most recent checkpoint.
         1221  +*/
         1222  +int lsmCheckpointSize(lsm_db *db, int *pnKB){
  1190   1223     ShmHeader *pShm = db->pShmhdr;
  1191   1224     int rc = LSM_OK;
  1192   1225     u32 nSynced;
  1193   1226   
         1227  +  /* Set nSynced to the number of pages that had been written when the 
         1228  +  ** database was last checkpointed. */
  1194   1229     rc = lsmCheckpointSynced(db, 0, 0, &nSynced);
         1230  +
  1195   1231     if( rc==LSM_OK ){
  1196   1232       u32 nPgsz = db->pShmhdr->aSnap1[CKPT_HDR_PGSZ];
  1197   1233       u32 nWrite = db->pShmhdr->aSnap1[CKPT_HDR_NWRITE];
  1198         -    *pnByte = (int)((nWrite - nSynced) * nPgsz);
         1234  +    *pnKB = (int)(( ((i64)(nWrite - nSynced) * nPgsz) + 1023) / 1024);
  1199   1235     }
  1200   1236   
  1201   1237     return rc;
  1202   1238   }
  1203   1239   

Changes to src/lsm_file.c.

   217    217   **   are carrying pointers into the database file mapping (pMap/nMap). If the
   218    218   **   file has to be unmapped and then remapped (required to grow the mapping
   219    219   **   as the file grows), the Page.aData pointers are updated by iterating
   220    220   **   through the contents of this list.
   221    221   **
   222    222   **   In non-mmap() mode, this list is an LRU list of cached pages with 
   223    223   **   nRef==0.
          224  +**
          225  +** apHash, nHash:
   224    226   */
   225    227   struct FileSystem {
   226    228     lsm_db *pDb;                    /* Database handle that owns this object */
   227    229     lsm_env *pEnv;                  /* Environment pointer */
   228    230     char *zDb;                      /* Database file name */
   229    231     char *zLog;                     /* Database file name */
   230    232     int nMetasize;                  /* Size of meta pages in bytes */
................................................................................
   349    351   **     lsmEnvSync()
   350    352   **     lsmEnvSectorSize()
   351    353   **     lsmEnvClose()
   352    354   **     lsmEnvTruncate()
   353    355   **     lsmEnvUnlink()
   354    356   **     lsmEnvRemap()
   355    357   */
   356         -int lsmEnvOpen(lsm_env *pEnv, const char *zFile, lsm_file **ppNew){
   357         -  return pEnv->xOpen(pEnv, zFile, ppNew);
          358  +int lsmEnvOpen(lsm_env *pEnv, const char *zFile, int flags, lsm_file **ppNew){
          359  +  return pEnv->xOpen(pEnv, zFile, flags, ppNew);
   358    360   }
   359    361   static int lsmEnvRead(
   360    362     lsm_env *pEnv, 
   361    363     lsm_file *pFile, 
   362    364     lsm_i64 iOff, 
   363    365     void *pRead, 
   364    366     int nRead
................................................................................
   419    421     return pEnv->xMap(pFile, iOff, szMin, ppMap, pszMap);
   420    422   }
   421    423   
   422    424   int lsmEnvLock(lsm_env *pEnv, lsm_file *pFile, int iLock, int eLock){
   423    425     if( pFile==0 ) return LSM_OK;
   424    426     return pEnv->xLock(pFile, iLock, eLock);
   425    427   }
          428  +
          429  +int lsmEnvTestLock(
          430  +  lsm_env *pEnv, 
          431  +  lsm_file *pFile, 
          432  +  int iLock, 
          433  +  int nLock, 
          434  +  int eLock
          435  +){
          436  +  return pEnv->xTestLock(pFile, iLock, nLock, eLock);
          437  +}
   426    438   
   427    439   int lsmEnvShmMap(
   428    440     lsm_env *pEnv, 
   429    441     lsm_file *pFile, 
   430    442     int iChunk, 
   431    443     int sz, 
   432    444     void **ppOut
................................................................................
   484    496   */
   485    497   int lsmFsTruncateLog(FileSystem *pFS, i64 nByte){
   486    498     if( pFS->fdLog==0 ) return LSM_OK;
   487    499     return lsmEnvTruncate(pFS->pEnv, pFS->fdLog, nByte);
   488    500   }
   489    501   
   490    502   /*
   491         -** Truncate the log file to nByte bytes in size.
          503  +** Truncate the db file to nByte bytes in size.
   492    504   */
   493    505   int lsmFsTruncateDb(FileSystem *pFS, i64 nByte){
   494    506     if( pFS->fdDb==0 ) return LSM_OK;
   495    507     return lsmEnvTruncate(pFS->pEnv, pFS->fdDb, nByte);
   496    508   }
   497    509   
   498    510   /*
................................................................................
   525    537   
   526    538   /*
   527    539   ** This is a helper function for lsmFsOpen(). It opens a single file on
   528    540   ** disk (either the database or log file).
   529    541   */
   530    542   static lsm_file *fsOpenFile(
   531    543     FileSystem *pFS,                /* File system object */
          544  +  int bReadonly,                  /* True to open this file read-only */
   532    545     int bLog,                       /* True for log, false for db */
   533    546     int *pRc                        /* IN/OUT: Error code */
   534    547   ){
   535    548     lsm_file *pFile = 0;
   536    549     if( *pRc==LSM_OK ){
   537         -    *pRc = lsmEnvOpen(pFS->pEnv, (bLog ? pFS->zLog : pFS->zDb), &pFile);
          550  +    int flags = (bReadonly ? LSM_OPEN_READONLY : 0);
          551  +    const char *zPath = (bLog ? pFS->zLog : pFS->zDb);
          552  +
          553  +    *pRc = lsmEnvOpen(pFS->pEnv, zPath, flags, &pFile);
   538    554     }
   539    555     return pFile;
   540    556   }
   541    557   
   542    558   
   543    559   static void fsGrowMapping(
   544    560     FileSystem *pFS,
................................................................................
   789    805   **
   790    806   ** The log file must be opened before any of the following may be called:
   791    807   **
   792    808   **     lsmFsWriteLog
   793    809   **     lsmFsSyncLog
   794    810   **     lsmFsReadLog
   795    811   */
   796         -int lsmFsOpenLog(FileSystem *pFS){
          812  +int lsmFsOpenLog(lsm_db *db, int *pbOpen){
   797    813     int rc = LSM_OK;
   798         -  if( 0==pFS->fdLog ){ pFS->fdLog = fsOpenFile(pFS, 1, &rc); }
          814  +  FileSystem *pFS = db->pFS;
          815  +
          816  +  if( 0==pFS->fdLog ){ 
          817  +    pFS->fdLog = fsOpenFile(pFS, db->bReadonly, 1, &rc); 
          818  +
          819  +    if( rc==LSM_IOERR_NOENT && db->bReadonly ){
          820  +      rc = LSM_OK;
          821  +    }
          822  +  }
          823  +
          824  +  if( pbOpen ) *pbOpen = (pFS->fdLog!=0);
   799    825     return rc;
   800    826   }
          827  +
          828  +void lsmFsCloseLog(lsm_db *db){
          829  +  FileSystem *pFS = db->pFS;
          830  +  if( pFS->fdLog ){
          831  +    lsmEnvClose(pFS->pEnv, pFS->fdLog);
          832  +    pFS->fdLog = 0;
          833  +  }
          834  +}
   801    835   
   802    836   /*
   803    837   ** Open a connection to a database stored within the file-system (the
   804    838   ** "system of files").
          839  +**
          840  +** If parameter bReadonly is true, then open a read-only file-descriptor
          841  +** on the database file. It is possible that bReadonly will be false even
          842  +** if the user requested that pDb be opened read-only. This is because the
          843  +** file-descriptor may later on be recycled by a read-write connection.
          844  +** If the db file can be opened for read-write access, it always is. Parameter
          845  +** bReadonly is only ever true if it has already been determined that the
          846  +** db can only be opened for read-only access.
   805    847   */
   806         -int lsmFsOpen(lsm_db *pDb, const char *zDb){
          848  +int lsmFsOpen(
          849  +  lsm_db *pDb,                    /* Database connection to open fd for */
          850  +  const char *zDb,                /* Full path to database file */
          851  +  int bReadonly                   /* True to open db file read-only */
          852  +){
   807    853     FileSystem *pFS;
   808    854     int rc = LSM_OK;
   809    855     int nDb = strlen(zDb);
   810    856     int nByte;
   811    857   
   812    858     assert( pDb->pFS==0 );
   813    859     assert( pDb->pWorker==0 && pDb->pClient==0 );
................................................................................
   819    865       pFS->zDb = (char *)&pFS[1];
   820    866       pFS->zLog = &pFS->zDb[nDb+1];
   821    867       pFS->nPagesize = LSM_DFLT_PAGE_SIZE;
   822    868       pFS->nBlocksize = LSM_DFLT_BLOCK_SIZE;
   823    869       pFS->nMetasize = 4 * 1024;
   824    870       pFS->pDb = pDb;
   825    871       pFS->pEnv = pDb->pEnv;
   826         -    if( pDb->compress.xCompress ){
   827         -      pFS->pCompress = &pDb->compress;
   828         -    }else{
          872  +    if( !pDb->compress.xCompress ){
   829    873         pFS->mmapmgr.eUseMmap = pDb->eMmap;
   830    874         pFS->mmapmgr.nMapsz = 1*1024*1024;
   831    875   
   832    876         pFS->mmapmgr.nMapsz = 4*1024;
   833    877       }
   834    878   
   835    879       /* Make a copy of the database and log file names. */
................................................................................
   848    892       if( pLsmFile ){
   849    893         pFS->pLsmFile = pLsmFile;
   850    894         pFS->fdDb = pLsmFile->pFile;
   851    895         memset(pLsmFile, 0, sizeof(LsmFile));
   852    896       }else{
   853    897         pFS->pLsmFile = lsmMallocZeroRc(pDb->pEnv, sizeof(LsmFile), &rc);
   854    898         if( rc==LSM_OK ){
   855         -        pFS->fdDb = fsOpenFile(pFS, 0, &rc);
          899  +        pFS->fdDb = fsOpenFile(pFS, bReadonly, 0, &rc);
   856    900         }
   857    901       }
   858    902   
   859    903       if( rc!=LSM_OK ){
   860    904         lsmFsClose(pFS);
   861    905         pFS = 0;
   862    906       }else{
................................................................................
   863    907         pFS->szSector = lsmEnvSectorSize(pFS->pEnv, pFS->fdDb);
   864    908       }
   865    909     }
   866    910   
   867    911     pDb->pFS = pFS;
   868    912     return rc;
   869    913   }
          914  +
          915  +/*
          916  +** Configure the file-system object according to the current values of
          917  +** the LSM_CONFIG_MMAP and LSM_CONFIG_SET_COMPRESSION options.
          918  +*/
          919  +int lsmFsConfigure(lsm_db *db){
          920  +  FileSystem *pFS = db->pFS;
          921  +  if( pFS ){
          922  +    lsm_env *pEnv = pFS->pEnv;
          923  +    Page *pPg;
          924  +
          925  +    assert( pFS->nOut==0 );
          926  +    assert( pFS->pWaiting==0 );
          927  +
          928  +    /* Reset any compression/decompression buffers already allocated */
          929  +    lsmFree(pEnv, pFS->aIBuffer);
          930  +    lsmFree(pEnv, pFS->aOBuffer);
          931  +    pFS->nBuffer = 0;
          932  +
          933  +    /* Unmap the file, if it is currently mapped */
          934  +    if( pFS->pMap ){
          935  +      lsmEnvRemap(pEnv, pFS->fdDb, -1, &pFS->pMap, &pFS->nMap);
          936  +      pFS->bUseMmap = 0;
          937  +    }
          938  +
          939  +    /* Free all allocate page structures */
          940  +    pPg = pFS->pLruFirst;
          941  +    while( pPg ){
          942  +      Page *pNext = pPg->pLruNext;
          943  +      if( pPg->flags & PAGE_FREE ) lsmFree(pEnv, pPg->aData);
          944  +      lsmFree(pEnv, pPg);
          945  +      pPg = pNext;
          946  +    }
          947  +
          948  +    /* Zero pointers that point to deleted page objects */
          949  +    pFS->nCacheAlloc = 0;
          950  +    pFS->pLruFirst = 0;
          951  +    pFS->pLruLast = 0;
          952  +    pFS->pFree = 0;
          953  +
          954  +    /* Configure the FileSystem object */
          955  +    if( db->compress.xCompress ){
          956  +      pFS->pCompress = &db->compress;
          957  +      pFS->bUseMmap = 0;
          958  +    }else{
          959  +      pFS->pCompress = 0;
          960  +      pFS->bUseMmap = db->bMmap;
          961  +    }
          962  +  }
          963  +
          964  +  return LSM_OK;
          965  +}
   870    966   
   871    967   /*
   872    968   ** Close and destroy a FileSystem object.
   873    969   */
   874    970   void lsmFsClose(FileSystem *pFS){
   875    971     if( pFS ){
   876    972       Page *pPg;
................................................................................
  1545   1641   
  1546   1642       p->aData = fsMmapRef(pFS, iOff, pFS->nPagesize, &p->pRef, &rc);
  1547   1643       if( rc!=LSM_OK ){
  1548   1644         p->pHashNext = pFS->pFree;
  1549   1645         pFS->pFree = p;
  1550   1646         p = 0;
  1551   1647       }
         1648  +
         1649  +    assert( (p->flags & PAGE_FREE)==0 );
  1552   1650     }else{
  1553   1651   
  1554   1652       /* Search the hash-table for the page */
  1555   1653       iHash = fsHashKey(pFS->nHash, iReal);
  1556   1654       for(p=pFS->apHash[iHash]; p; p=p->pHashNext){
  1557   1655         if( p->iPg==iReal) break;
  1558   1656       }

Changes to src/lsm_log.c.

   201    201   #define LSM_LOG_WRITE_CKSUM  0x07
   202    202   #define LSM_LOG_DELETE       0x08
   203    203   #define LSM_LOG_DELETE_CKSUM 0x09
   204    204   
   205    205   /* Require a checksum every 32KB. */
   206    206   #define LSM_CKSUM_MAXDATA (32*1024)
   207    207   
          208  +/* Do not wrap a log file smaller than this in bytes. */
          209  +#define LSM_MIN_LOGWRAP      (128*1024)
          210  +
   208    211   /*
   209    212   ** szSector:
   210    213   **   Commit records must be aligned to end on szSector boundaries. If
   211    214   **   the safety-mode is set to NORMAL or OFF, this value is 1. Otherwise,
   212    215   **   if the safety-mode is set to FULL, it is the size of the file-system
   213    216   **   sectors as reported by lsmFsSectorSize().
   214    217   */
................................................................................
   297    300   
   298    301   /*
   299    302   ** If possible, reclaim log file space. Log file space is reclaimed after
   300    303   ** a snapshot that points to the same data in the database file is synced
   301    304   ** into the db header.
   302    305   */
   303    306   static int logReclaimSpace(lsm_db *pDb){
   304         -  int rc = LSM_OK;
          307  +  int rc;
   305    308     int iMeta;
          309  +  int bRotrans;                   /* True if there exists some ro-trans */
          310  +
          311  +  /* Test if there exists some other connection with a read-only transaction
          312  +  ** open. If there does, then log file space may not be reclaimed.  */
          313  +  rc = lsmDetectRoTrans(pDb, &bRotrans);
          314  +  if( rc!=LSM_OK || bRotrans ) return rc;
   306    315   
   307    316     iMeta = (int)pDb->pShmhdr->iMetaPage;
   308    317     if( iMeta==1 || iMeta==2 ){
   309    318       DbLog *pLog = &pDb->treehdr.log;
   310    319       i64 iSyncedId;
   311    320   
   312    321       /* Read the snapshot-id of the snapshot stored on meta-page iMeta. Note
................................................................................
   353    362     LogWriter *pNew;
   354    363     LogRegion *aReg;
   355    364   
   356    365     if( pDb->bUseLog==0 ) return LSM_OK;
   357    366   
   358    367     /* If the log file has not yet been opened, open it now. Also allocate
   359    368     ** the LogWriter structure, if it has not already been allocated.  */
   360         -  rc = lsmFsOpenLog(pDb->pFS);
          369  +  rc = lsmFsOpenLog(pDb, 0);
   361    370     if( pDb->pLogWriter==0 ){
   362    371       pNew = lsmMallocZeroRc(pDb->pEnv, sizeof(LogWriter), &rc);
   363    372       if( pNew ){
   364    373         lsmStringInit(&pNew->buf, pDb->pEnv);
   365    374         rc = lsmStringExtend(&pNew->buf, 2);
   366    375       }
   367    376     }else{
................................................................................
   399    408     }else{
   400    409       pNew->szSector = 1;
   401    410     }
   402    411   
   403    412     /* There are now three scenarios:
   404    413     **
   405    414     **   1) Regions 0 and 1 are both zero bytes in size and region 2 begins
   406         -  **      at a file offset greater than N, where N is the value configured
   407         -  **      by LSM_CONFIG_LOG_SIZE. In this case, wrap around to the start
   408         -  **      and write data into the start of the log file. 
          415  +  **      at a file offset greater than LSM_MIN_LOGWRAP. In this case, wrap
          416  +  **      around to the start and write data into the start of the log file. 
   409    417     **
   410    418     **   2) Region 1 is zero bytes in size and region 2 occurs earlier in the 
   411    419     **      file than region 0. In this case, append data to region 2, but
   412    420     **      remember to jump over region 1 if required.
   413    421     **
   414    422     **   3) Region 2 is the last in the file. Append to it.
   415    423     */
................................................................................
   417    425   
   418    426     assert( aReg[0].iEnd==0 || aReg[0].iEnd>aReg[0].iStart );
   419    427     assert( aReg[1].iEnd==0 || aReg[1].iEnd>aReg[1].iStart );
   420    428   
   421    429     pNew->cksum0 = pDb->treehdr.log.cksum0;
   422    430     pNew->cksum1 = pDb->treehdr.log.cksum1;
   423    431   
   424         -  if( aReg[0].iEnd==0 && aReg[1].iEnd==0 && aReg[2].iStart>=pDb->nLogSz ){
          432  +  if( aReg[0].iEnd==0 && aReg[1].iEnd==0 && aReg[2].iStart>=LSM_MIN_LOGWRAP ){
   425    433       /* Case 1. Wrap around to the start of the file. Write an LSM_LOG_JUMP 
   426    434       ** into the log file in this case. Pad it out to 8 bytes using a PAD2
   427    435       ** record so that the checksums can be updated immediately.  */
   428    436       u8 aJump[] = { 
   429    437         LSM_LOG_PAD2, 0x04, 0x00, 0x00, 0x00, 0x00, LSM_LOG_JUMP, 0x00 
   430    438       };
   431    439   
................................................................................
   952    960     LsmString buf2;                 /* Value buffer */
   953    961     LogReader reader;               /* Log reader object */
   954    962     int rc = LSM_OK;                /* Return code */
   955    963     int nCommit = 0;                /* Number of transactions to recover */
   956    964     int iPass;
   957    965     int nJump = 0;                  /* Number of LSM_LOG_JUMP records in pass 0 */
   958    966     DbLog *pLog;
          967  +  int bOpen;
   959    968   
   960         -  rc = lsmFsOpenLog(pDb->pFS);
          969  +  rc = lsmFsOpenLog(pDb, &bOpen);
   961    970     if( rc!=LSM_OK ) return rc;
   962    971   
   963    972     rc = lsmTreeInit(pDb);
   964    973     if( rc!=LSM_OK ) return rc;
   965    974   
   966    975     pLog = &pDb->treehdr.log;
   967    976     lsmCheckpointLogoffset(pDb->pShmhdr->aSnap2, pLog);
................................................................................
   970    979     lsmStringInit(&buf1, pDb->pEnv);
   971    980     lsmStringInit(&buf2, pDb->pEnv);
   972    981   
   973    982     /* The outer for() loop runs at most twice. The first iteration is to 
   974    983     ** count the number of committed transactions in the log. The second 
   975    984     ** iterates through those transactions and updates the in-memory tree 
   976    985     ** structure with their contents.  */
   977         -  for(iPass=0; iPass<2 && rc==LSM_OK; iPass++){
   978         -    int bEof = 0;
   979         -
   980         -    while( rc==LSM_OK && !bEof ){
   981         -      u8 eType = 0;
   982         -      logReaderByte(&reader, &eType, &rc);
   983         -
   984         -      switch( eType ){
   985         -        case LSM_LOG_PAD1:
   986         -          break;
   987         -
   988         -        case LSM_LOG_PAD2: {
   989         -          int nPad;
   990         -          logReaderVarint(&reader, &buf1, &nPad, &rc);
   991         -          logReaderBlob(&reader, &buf1, nPad, 0, &rc);
   992         -          break;
   993         -        }
   994         -
   995         -        case LSM_LOG_WRITE:
   996         -        case LSM_LOG_WRITE_CKSUM: {
   997         -          int nKey;
   998         -          int nVal;
   999         -          u8 *aVal;
  1000         -          logReaderVarint(&reader, &buf1, &nKey, &rc);
  1001         -          logReaderVarint(&reader, &buf2, &nVal, &rc);
  1002         -
  1003         -          if( eType==LSM_LOG_WRITE_CKSUM ){
  1004         -            logReaderCksum(&reader, &buf1, &bEof, &rc);
  1005         -          }else{
  1006         -            bEof = logRequireCksum(&reader, nKey+nVal);
          986  +  if( bOpen ){
          987  +    for(iPass=0; iPass<2 && rc==LSM_OK; iPass++){
          988  +      int bEof = 0;
          989  +
          990  +      while( rc==LSM_OK && !bEof ){
          991  +        u8 eType = 0;
          992  +        logReaderByte(&reader, &eType, &rc);
          993  +
          994  +        switch( eType ){
          995  +          case LSM_LOG_PAD1:
          996  +            break;
          997  +
          998  +          case LSM_LOG_PAD2: {
          999  +            int nPad;
         1000  +            logReaderVarint(&reader, &buf1, &nPad, &rc);
         1001  +            logReaderBlob(&reader, &buf1, nPad, 0, &rc);
         1002  +            break;
         1003  +          }
         1004  +
         1005  +          case LSM_LOG_WRITE:
         1006  +          case LSM_LOG_WRITE_CKSUM: {
         1007  +            int nKey;
         1008  +            int nVal;
         1009  +            u8 *aVal;
         1010  +            logReaderVarint(&reader, &buf1, &nKey, &rc);
         1011  +            logReaderVarint(&reader, &buf2, &nVal, &rc);
         1012  +
         1013  +            if( eType==LSM_LOG_WRITE_CKSUM ){
         1014  +              logReaderCksum(&reader, &buf1, &bEof, &rc);
         1015  +            }else{
         1016  +              bEof = logRequireCksum(&reader, nKey+nVal);
         1017  +            }
         1018  +            if( bEof ) break;
         1019  +
         1020  +            logReaderBlob(&reader, &buf1, nKey, 0, &rc);
         1021  +            logReaderBlob(&reader, &buf2, nVal, &aVal, &rc);
         1022  +            if( iPass==1 && rc==LSM_OK ){ 
         1023  +              rc = lsmTreeInsert(pDb, (u8 *)buf1.z, nKey, aVal, nVal);
         1024  +            }
         1025  +            break;
         1026  +          }
         1027  +
         1028  +          case LSM_LOG_DELETE:
         1029  +          case LSM_LOG_DELETE_CKSUM: {
         1030  +            int nKey; u8 *aKey;
         1031  +            logReaderVarint(&reader, &buf1, &nKey, &rc);
         1032  +
         1033  +            if( eType==LSM_LOG_DELETE_CKSUM ){
         1034  +              logReaderCksum(&reader, &buf1, &bEof, &rc);
         1035  +            }else{
         1036  +              bEof = logRequireCksum(&reader, nKey);
         1037  +            }
         1038  +            if( bEof ) break;
         1039  +
         1040  +            logReaderBlob(&reader, &buf1, nKey, &aKey, &rc);
         1041  +            if( iPass==1 && rc==LSM_OK ){ 
         1042  +              rc = lsmTreeInsert(pDb, aKey, nKey, NULL, -1);
         1043  +            }
         1044  +            break;
  1007   1045             }
  1008         -          if( bEof ) break;
  1009   1046   
  1010         -          logReaderBlob(&reader, &buf1, nKey, 0, &rc);
  1011         -          logReaderBlob(&reader, &buf2, nVal, &aVal, &rc);
  1012         -          if( iPass==1 && rc==LSM_OK ){ 
  1013         -            rc = lsmTreeInsert(pDb, (u8 *)buf1.z, nKey, aVal, nVal);
  1014         -          }
  1015         -          break;
  1016         -        }
  1017         -
  1018         -        case LSM_LOG_DELETE:
  1019         -        case LSM_LOG_DELETE_CKSUM: {
  1020         -          int nKey; u8 *aKey;
  1021         -          logReaderVarint(&reader, &buf1, &nKey, &rc);
  1022         -
  1023         -          if( eType==LSM_LOG_DELETE_CKSUM ){
         1047  +          case LSM_LOG_COMMIT:
  1024   1048               logReaderCksum(&reader, &buf1, &bEof, &rc);
  1025         -          }else{
  1026         -            bEof = logRequireCksum(&reader, nKey);
  1027         -          }
  1028         -          if( bEof ) break;
  1029         -
  1030         -          logReaderBlob(&reader, &buf1, nKey, &aKey, &rc);
  1031         -          if( iPass==1 && rc==LSM_OK ){ 
  1032         -            rc = lsmTreeInsert(pDb, aKey, nKey, NULL, -1);
  1033         -          }
  1034         -          break;
  1035         -        }
         1049  +            if( bEof==0 ){
         1050  +              nCommit++;
         1051  +              assert( nCommit>0 || iPass==1 );
         1052  +              if( nCommit==0 ) bEof = 1;
         1053  +            }
         1054  +            break;
  1036   1055   
  1037         -        case LSM_LOG_COMMIT:
  1038         -          logReaderCksum(&reader, &buf1, &bEof, &rc);
  1039         -          if( bEof==0 ){
  1040         -            nCommit++;
  1041         -            assert( nCommit>0 || iPass==1 );
  1042         -            if( nCommit==0 ) bEof = 1;
  1043         -          }
  1044         -          break;
  1045         -
  1046         -        case LSM_LOG_JUMP: {
  1047         -          int iOff = 0;
  1048         -          logReaderVarint(&reader, &buf1, &iOff, &rc);
  1049         -          if( rc==LSM_OK ){
  1050         -            if( iPass==1 ){
  1051         -              if( pLog->aRegion[2].iStart==0 ){
  1052         -                assert( pLog->aRegion[1].iStart==0 );
  1053         -                pLog->aRegion[1].iEnd = reader.iOff;
         1056  +          case LSM_LOG_JUMP: {
         1057  +            int iOff = 0;
         1058  +            logReaderVarint(&reader, &buf1, &iOff, &rc);
         1059  +            if( rc==LSM_OK ){
         1060  +              if( iPass==1 ){
         1061  +                if( pLog->aRegion[2].iStart==0 ){
         1062  +                  assert( pLog->aRegion[1].iStart==0 );
         1063  +                  pLog->aRegion[1].iEnd = reader.iOff;
         1064  +                }else{
         1065  +                  assert( pLog->aRegion[0].iStart==0 );
         1066  +                  pLog->aRegion[0].iStart = pLog->aRegion[2].iStart;
         1067  +                  pLog->aRegion[0].iEnd = reader.iOff-reader.buf.n+reader.iBuf;
         1068  +                }
         1069  +                pLog->aRegion[2].iStart = iOff;
  1054   1070                 }else{
  1055         -                assert( pLog->aRegion[0].iStart==0 );
  1056         -                pLog->aRegion[0].iStart = pLog->aRegion[2].iStart;
  1057         -                pLog->aRegion[0].iEnd = reader.iOff - reader.buf.n+reader.iBuf;
         1071  +                if( (nJump++)==2 ){
         1072  +                  bEof = 1;
         1073  +                }
  1058   1074                 }
  1059         -              pLog->aRegion[2].iStart = iOff;
  1060         -            }else{
  1061         -              if( (nJump++)==2 ){
  1062         -                bEof = 1;
  1063         -              }
         1075  +
         1076  +              reader.iOff = iOff;
         1077  +              reader.buf.n = reader.iBuf;
  1064   1078               }
         1079  +            break;
         1080  +          }
  1065   1081   
  1066         -            reader.iOff = iOff;
  1067         -            reader.buf.n = reader.iBuf;
  1068         -          }
  1069         -          break;
  1070         -        }
  1071         -
  1072         -        default:
  1073         -          /* Including LSM_LOG_EOF */
  1074         -          bEof = 1;
  1075         -          break;
  1076         -      }
  1077         -    }
  1078         -
  1079         -    if( rc==LSM_OK && iPass==0 ){
  1080         -      if( nCommit==0 ){
  1081         -        if( pLog->aRegion[2].iStart==0 ){
  1082         -          iPass = 1;
  1083         -        }else{
  1084         -          pLog->aRegion[2].iStart = 0;
  1085         -          iPass = -1;
  1086         -          lsmCheckpointZeroLogoffset(pDb);
         1082  +          default:
         1083  +            /* Including LSM_LOG_EOF */
         1084  +            bEof = 1;
         1085  +            break;
  1087   1086           }
  1088   1087         }
  1089         -      logReaderInit(pDb, pLog, 0, &reader);
  1090         -      nCommit = nCommit * -1;
         1088  +
         1089  +      if( rc==LSM_OK && iPass==0 ){
         1090  +        if( nCommit==0 ){
         1091  +          if( pLog->aRegion[2].iStart==0 ){
         1092  +            iPass = 1;
         1093  +          }else{
         1094  +            pLog->aRegion[2].iStart = 0;
         1095  +            iPass = -1;
         1096  +            lsmCheckpointZeroLogoffset(pDb);
         1097  +          }
         1098  +        }
         1099  +        logReaderInit(pDb, pLog, 0, &reader);
         1100  +        nCommit = nCommit * -1;
         1101  +      }
  1091   1102       }
  1092   1103     }
  1093   1104   
  1094   1105     /* Initialize DbLog object */
  1095   1106     if( rc==LSM_OK ){
  1096   1107       pLog->aRegion[2].iEnd = reader.iOff - reader.buf.n + reader.iBuf;
  1097   1108       pLog->cksum0 = reader.cksum0;
................................................................................
  1099   1110     }
  1100   1111   
  1101   1112     if( rc==LSM_OK ){
  1102   1113       rc = lsmFinishRecovery(pDb);
  1103   1114     }else{
  1104   1115       lsmFinishRecovery(pDb);
  1105   1116     }
         1117  +
         1118  +  if( pDb->bRoTrans ){
         1119  +    lsmFsCloseLog(pDb);
         1120  +  }
  1106   1121   
  1107   1122     lsmStringClear(&buf1);
  1108   1123     lsmStringClear(&buf2);
  1109   1124     lsmStringClear(&reader.buf);
  1110   1125     return rc;
  1111   1126   }
  1112   1127   

Changes to src/lsm_main.c.

    35     35   */
    36     36   static void assert_db_state(lsm_db *pDb){
    37     37   
    38     38     /* If there is at least one cursor or a write transaction open, the database
    39     39     ** handle must be holding a pointer to a client snapshot. And the reverse 
    40     40     ** - if there are no open cursors and no write transactions then there must 
    41     41     ** not be a client snapshot.  */
    42         -  assert( (pDb->pCsr!=0 || pDb->nTransOpen>0)==(pDb->iReader>=0) );
           42  +  
           43  +  assert( (pDb->pCsr!=0||pDb->nTransOpen>0)==(pDb->iReader>=0||pDb->bRoTrans) );
    43     44   
    44         -  assert( pDb->iReader<0 || pDb->pClient!=0 );
           45  +  assert( (pDb->iReader<0 && pDb->bRoTrans==0) || pDb->pClient!=0 );
    45     46   
    46     47     assert( pDb->nTransOpen>=0 );
    47     48   }
    48     49   #else
    49     50   # define assert_db_state(x) 
    50     51   #endif
    51     52   
................................................................................
    83     84     /* Initialize the new object */
    84     85     pDb->pEnv = pEnv;
    85     86     pDb->nTreeLimit = LSM_DFLT_AUTOFLUSH;
    86     87     pDb->nAutockpt = LSM_DFLT_AUTOCHECKPOINT;
    87     88     pDb->bAutowork = LSM_DFLT_AUTOWORK;
    88     89     pDb->eSafety = LSM_DFLT_SAFETY;
    89     90     pDb->xCmp = xCmp;
    90         -  pDb->nLogSz = LSM_DFLT_LOG_SIZE;
    91     91     pDb->nDfltPgsz = LSM_DFLT_PAGE_SIZE;
    92     92     pDb->nDfltBlksz = LSM_DFLT_BLOCK_SIZE;
    93     93     pDb->nMerge = LSM_DFLT_AUTOMERGE;
    94     94     pDb->nMaxFreelist = LSM_MAX_FREELIST_ENTRIES;
    95     95     pDb->bUseLog = LSM_DFLT_USE_LOG;
    96     96     pDb->iReader = -1;
           97  +  pDb->iRwclient = -1;
    97     98     pDb->bMultiProc = LSM_DFLT_MULTIPLE_PROCESSES;
    98     99     pDb->eMmap = LSM_DFLT_MMAP;
    99    100     pDb->xLog = xLog;
          101  +  pDb->compress.iId = LSM_COMPRESSION_NONE;
   100    102     return LSM_OK;
   101    103   }
   102    104   
   103    105   lsm_env *lsm_get_env(lsm_db *pDb){
   104    106     assert( pDb->pEnv );
   105    107     return pDb->pEnv;
   106    108   }
................................................................................
   136    138     if( rc!=LSM_OK ){
   137    139       lsmFree(pEnv, zAlloc);
   138    140       zAlloc = 0;
   139    141     }
   140    142     *pzAbs = zAlloc;
   141    143     return rc;
   142    144   }
          145  +
          146  +/*
          147  +** Check that the bits in the db->mLock mask are consistent with the
          148  +** value stored in db->iRwclient. An assert shall fail otherwise.
          149  +*/
          150  +static void assertRwclientLockValue(lsm_db *db){
          151  +#ifndef NDEBUG
          152  +  u64 msk;                        /* Mask of mLock bits for RWCLIENT locks */
          153  +  u64 rwclient = 0;               /* Bit corresponding to db->iRwclient */
          154  +
          155  +  if( db->iRwclient>=0 ){
          156  +    rwclient = ((u64)1 << (LSM_LOCK_RWCLIENT(db->iRwclient)-1));
          157  +  }
          158  +  msk  = ((u64)1 << (LSM_LOCK_RWCLIENT(LSM_LOCK_NRWCLIENT)-1)) - 1;
          159  +  msk -= (((u64)1 << (LSM_LOCK_RWCLIENT(0)-1)) - 1);
          160  +
          161  +  assert( (db->mLock & msk)==rwclient );
          162  +#endif
          163  +}
   143    164   
   144    165   /*
   145    166   ** Open a new connection to database zFilename.
   146    167   */
   147    168   int lsm_open(lsm_db *pDb, const char *zFilename){
   148    169     int rc;
   149    170   
................................................................................
   158    179       ** than one purpose - to open both the database and log files, and 
   159    180       ** perhaps to unlink the log file during disconnection. An absolute
   160    181       ** path is required to ensure that the correct files are operated
   161    182       ** on even if the application changes the cwd.  */
   162    183       rc = getFullpathname(pDb->pEnv, zFilename, &zFull);
   163    184       assert( rc==LSM_OK || zFull==0 );
   164    185   
   165         -    /* Connect to the database */
          186  +    /* Connect to the database. */
   166    187       if( rc==LSM_OK ){
   167    188         rc = lsmDbDatabaseConnect(pDb, zFull);
   168    189       }
   169    190   
   170         -    /* Configure the file-system connection with the page-size and block-size
   171         -    ** of this database. Even if the database file is zero bytes in size
   172         -    ** on disk, these values have been set in shared-memory by now, and so are
   173         -    ** guaranteed not to change during the lifetime of this connection.  */
   174         -    if( rc==LSM_OK && LSM_OK==(rc = lsmCheckpointLoad(pDb, 0)) ){
   175         -      lsmFsSetPageSize(pDb->pFS, lsmCheckpointPgsz(pDb->aSnapshot));
   176         -      lsmFsSetBlockSize(pDb->pFS, lsmCheckpointBlksz(pDb->aSnapshot));
          191  +    if( pDb->bReadonly==0 ){
          192  +      /* Configure the file-system connection with the page-size and block-size
          193  +      ** of this database. Even if the database file is zero bytes in size
          194  +      ** on disk, these values have been set in shared-memory by now, and so 
          195  +      ** are guaranteed not to change during the lifetime of this connection.  
          196  +      */
          197  +      if( rc==LSM_OK && LSM_OK==(rc = lsmCheckpointLoad(pDb, 0)) ){
          198  +        lsmFsSetPageSize(pDb->pFS, lsmCheckpointPgsz(pDb->aSnapshot));
          199  +        lsmFsSetBlockSize(pDb->pFS, lsmCheckpointBlksz(pDb->aSnapshot));
          200  +      }
   177    201       }
   178    202   
   179    203       lsmFree(pDb->pEnv, zFull);
          204  +    assertRwclientLockValue(pDb);
   180    205     }
   181    206   
          207  +  assert( pDb->bReadonly==0 || pDb->bReadonly==1 );
          208  +  assert( rc!=LSM_OK || (pDb->pShmhdr==0)==(pDb->bReadonly==1) );
          209  +
   182    210     return rc;
   183    211   }
   184         -
   185    212   
   186    213   int lsm_close(lsm_db *pDb){
   187    214     int rc = LSM_OK;
   188    215     if( pDb ){
   189    216       assert_db_state(pDb);
   190    217       if( pDb->pCsr || pDb->nTransOpen ){
   191    218         rc = LSM_MISUSE_BKPT;
   192    219       }else{
          220  +      lsmMCursorFreeCache(pDb);
   193    221         lsmFreeSnapshot(pDb->pEnv, pDb->pClient);
   194    222         pDb->pClient = 0;
          223  +
          224  +      assertRwclientLockValue(pDb);
          225  +
   195    226         lsmDbDatabaseRelease(pDb);
   196    227         lsmLogClose(pDb);
   197    228         lsmFsClose(pDb->pFS);
          229  +      assert( pDb->mLock==0 );
          230  +      
          231  +      /* Invoke any destructors registered for the compression or 
          232  +      ** compression factory callbacks.  */
          233  +      if( pDb->factory.xFree ) pDb->factory.xFree(pDb->factory.pCtx);
          234  +      if( pDb->compress.xFree ) pDb->compress.xFree(pDb->compress.pCtx);
          235  +
   198    236         lsmFree(pDb->pEnv, pDb->rollback.aArray);
   199    237         lsmFree(pDb->pEnv, pDb->aTrans);
   200    238         lsmFree(pDb->pEnv, pDb->apShm);
   201    239         lsmFree(pDb->pEnv, pDb);
   202    240       }
   203    241     }
   204    242     return rc;
................................................................................
   207    245   int lsm_config(lsm_db *pDb, int eParam, ...){
   208    246     int rc = LSM_OK;
   209    247     va_list ap;
   210    248     va_start(ap, eParam);
   211    249   
   212    250     switch( eParam ){
   213    251       case LSM_CONFIG_AUTOFLUSH: {
          252  +      /* This parameter is read and written in KB. But all internal 
          253  +      ** processing is done in bytes.  */
   214    254         int *piVal = va_arg(ap, int *);
   215         -      if( *piVal>=0 ){
   216         -        pDb->nTreeLimit = *piVal;
          255  +      int iVal = *piVal;
          256  +      if( iVal>=0 && iVal<=(1024*1024) ){
          257  +        pDb->nTreeLimit = iVal*1024;
   217    258         }
   218         -      *piVal = pDb->nTreeLimit;
          259  +      *piVal = (pDb->nTreeLimit / 1024);
   219    260         break;
   220    261       }
   221    262   
   222    263       case LSM_CONFIG_AUTOWORK: {
   223    264         int *piVal = va_arg(ap, int *);
   224    265         if( *piVal>=0 ){
   225    266           pDb->bAutowork = *piVal;
   226    267         }
   227    268         *piVal = pDb->bAutowork;
   228    269         break;
   229    270       }
   230    271   
   231    272       case LSM_CONFIG_AUTOCHECKPOINT: {
          273  +      /* This parameter is read and written in KB. But all internal processing
          274  +      ** (including the lsm_db.nAutockpt variable) is done in bytes.  */
   232    275         int *piVal = va_arg(ap, int *);
   233    276         if( *piVal>=0 ){
   234         -        pDb->nAutockpt = *piVal;
          277  +        int iVal = *piVal;
          278  +        pDb->nAutockpt = (i64)iVal * 1024;
   235    279         }
   236         -      *piVal = pDb->nAutockpt;
   237         -      break;
   238         -    }
   239         -
   240         -    case LSM_CONFIG_LOG_SIZE: {
   241         -      int *piVal = va_arg(ap, int *);
   242         -      if( *piVal>0 ){
   243         -        pDb->nLogSz = *piVal;
   244         -      }
   245         -      *piVal = pDb->nLogSz;
          280  +      *piVal = (int)(pDb->nAutockpt / 1024);
   246    281         break;
   247    282       }
   248    283   
   249    284       case LSM_CONFIG_PAGE_SIZE: {
   250    285         int *piVal = va_arg(ap, int *);
   251    286         if( pDb->pDatabase ){
   252    287           /* If lsm_open() has been called, this is a read-only parameter. 
................................................................................
   260    295             *piVal = pDb->nDfltPgsz;
   261    296           }
   262    297         }
   263    298         break;
   264    299       }
   265    300   
   266    301       case LSM_CONFIG_BLOCK_SIZE: {
          302  +      /* This parameter is read and written in KB. But all internal 
          303  +      ** processing is done in bytes.  */
   267    304         int *piVal = va_arg(ap, int *);
   268    305         if( pDb->pDatabase ){
   269    306           /* If lsm_open() has been called, this is a read-only parameter. 
   270         -        ** Set the output variable to the page-size according to the 
          307  +        ** Set the output variable to the block-size in KB according to the 
   271    308           ** FileSystem object.  */
   272         -        *piVal = lsmFsBlockSize(pDb->pFS);
          309  +        *piVal = lsmFsBlockSize(pDb->pFS) / 1024;
   273    310         }else{
   274         -        if( *piVal>=65536 && ((*piVal-1) & *piVal)==0 ){
   275         -          pDb->nDfltBlksz = *piVal;
          311  +        int iVal = *piVal;
          312  +        if( iVal>=64 && iVal<=65536 && ((iVal-1) & iVal)==0 ){
          313  +          pDb->nDfltBlksz = iVal * 1024;
   276    314           }else{
   277         -          *piVal = pDb->nDfltBlksz;
          315  +          *piVal = pDb->nDfltBlksz / 1024;
   278    316           }
   279    317         }
   280    318         break;
   281    319       }
   282    320   
   283    321       case LSM_CONFIG_SAFETY: {
   284    322         int *piVal = va_arg(ap, int *);
................................................................................
   287    325         }
   288    326         *piVal = pDb->eSafety;
   289    327         break;
   290    328       }
   291    329   
   292    330       case LSM_CONFIG_MMAP: {
   293    331         int *piVal = va_arg(ap, int *);
   294         -      if( pDb->pDatabase==0 && (*piVal>=0 && *piVal<=2) ){
   295         -        pDb->eMmap = *piVal;
          332  +      if( pDb->iReader<0 && *piVal>=0 && *piVal<=1 ){
          333  +        pDb->bMmap = *piVal;
          334  +        rc = lsmFsConfigure(pDb);
   296    335         }
   297    336         *piVal = pDb->eMmap;
   298    337         break;
   299    338       }
   300    339   
   301    340       case LSM_CONFIG_USE_LOG: {
   302    341         int *piVal = va_arg(ap, int *);
................................................................................
   331    370           ** in multi-process mode.  */
   332    371           *piVal = lsmDbMultiProc(pDb);
   333    372         }else{
   334    373           pDb->bMultiProc = *piVal = (*piVal!=0);
   335    374         }
   336    375         break;
   337    376       }
          377  +
          378  +    case LSM_CONFIG_READONLY: {
          379  +      int *piVal = va_arg(ap, int *);
          380  +      /* If lsm_open() has been called, this is a read-only parameter. */
          381  +      if( pDb->pDatabase==0 && *piVal>=0 ){
          382  +        pDb->bReadonly = *piVal = (*piVal!=0);
          383  +      }
          384  +      *piVal = pDb->bReadonly;
          385  +      break;
          386  +    }
   338    387   
   339    388       case LSM_CONFIG_SET_COMPRESSION: {
   340    389         lsm_compress *p = va_arg(ap, lsm_compress *);
   341         -      if( pDb->pDatabase ){
   342         -        /* If lsm_open() has been called, this call is against the rules. */
          390  +      if( pDb->iReader>=0 && pDb->bInFactory==0 ){
          391  +        /* May not change compression schemes with an open transaction */
   343    392           rc = LSM_MISUSE_BKPT;
   344    393         }else{
   345         -        memcpy(&pDb->compress, p, sizeof(lsm_compress));
          394  +        if( pDb->compress.xFree ){
          395  +          /* Invoke any destructor belonging to the current compression. */
          396  +          pDb->compress.xFree(pDb->compress.pCtx);
          397  +        }
          398  +        if( p->xBound==0 ){
          399  +          memset(&pDb->compress, 0, sizeof(lsm_compress));
          400  +          pDb->compress.iId = LSM_COMPRESSION_NONE;
          401  +        }else{
          402  +          memcpy(&pDb->compress, p, sizeof(lsm_compress));
          403  +        }
          404  +        rc = lsmFsConfigure(pDb);
          405  +      }
          406  +      break;
          407  +    }
          408  +
          409  +    case LSM_CONFIG_SET_COMPRESSION_FACTORY: {
          410  +      lsm_compress_factory *p = va_arg(ap, lsm_compress_factory *);
          411  +      if( pDb->factory.xFree ){
          412  +        /* Invoke any destructor belonging to the current factory. */
          413  +        pDb->factory.xFree(pDb->factory.pCtx);
   346    414         }
          415  +      memcpy(&pDb->factory, p, sizeof(lsm_compress_factory));
   347    416         break;
   348    417       }
   349    418   
   350    419       case LSM_CONFIG_GET_COMPRESSION: {
   351    420         lsm_compress *p = va_arg(ap, lsm_compress *);
   352    421         memcpy(p, &pDb->compress, sizeof(lsm_compress));
   353    422         break;
................................................................................
   429    498     return 0;
   430    499   }
   431    500   
   432    501   int lsmInfoFreelist(lsm_db *pDb, char **pzOut){
   433    502     Snapshot *pWorker;              /* Worker snapshot */
   434    503     int bUnlock = 0;
   435    504     LsmString s;
   436         -  int i;
   437    505     int rc;
   438    506   
   439    507     /* Obtain the worker snapshot */
   440    508     rc = infoGetWorker(pDb, &pWorker, &bUnlock);
   441    509     if( rc!=LSM_OK ) return rc;
   442    510   
   443    511     lsmStringInit(&s, pDb->pEnv);
................................................................................
   449    517     }
   450    518   
   451    519     /* Release the snapshot and return */
   452    520     infoFreeWorker(pDb, bUnlock);
   453    521     return rc;
   454    522   }
   455    523   
   456         -static int infoFreelistSize(lsm_db *pDb, int *pnFree, int *pnWaiting){
   457         -}
   458         -
   459         -static int infoTreeSize(lsm_db *db, int *pnOld, int *pnNew){
          524  +static int infoTreeSize(lsm_db *db, int *pnOldKB, int *pnNewKB){
   460    525     ShmHeader *pShm = db->pShmhdr;
   461    526     TreeHeader *p = &pShm->hdr1;
   462    527   
   463    528     /* The following code suffers from two race conditions, as it accesses and
   464    529     ** trusts the contents of shared memory without verifying checksums:
   465    530     **
   466    531     **   * The two values read - TreeHeader.root.nByte and oldroot.nByte - are 
................................................................................
   475    540     **     for the size of the "old" tree may reflect the size of an "old"
   476    541     **     tree that was recently flushed to disk.
   477    542     **
   478    543     ** Given the context in which this function is called (as a result of an
   479    544     ** lsm_info(LSM_INFO_TREE_SIZE) request), neither of these are considered to
   480    545     ** be problems.
   481    546     */
   482         -  *pnNew = (int)p->root.nByte;
          547  +  *pnNewKB = ((int)p->root.nByte + 1023) / 1024;
   483    548     if( p->iOldShmid ){
   484    549       if( p->iOldLog==lsmCheckpointLogOffset(pShm->aSnap1) ){
   485         -      *pnOld = 0;
          550  +      *pnOldKB = 0;
   486    551       }else{
   487         -      *pnOld = (int)p->oldroot.nByte;
          552  +      *pnOldKB = ((int)p->oldroot.nByte + 1023) / 1024;
   488    553       }
   489    554     }else{
   490         -    *pnOld = 0;
          555  +    *pnOldKB = 0;
   491    556     }
   492    557   
   493    558     return LSM_OK;
   494    559   }
   495    560   
   496    561   int lsm_info(lsm_db *pDb, int eParam, ...){
   497    562     int rc = LSM_OK;
................................................................................
   554    619       case LSM_INFO_FREELIST: {
   555    620         char **pzVal = va_arg(ap, char **);
   556    621         rc = lsmInfoFreelist(pDb, pzVal);
   557    622         break;
   558    623       }
   559    624   
   560    625       case LSM_INFO_CHECKPOINT_SIZE: {
   561         -      int *pnByte = va_arg(ap, int *);
   562         -      rc = lsmCheckpointSize(pDb, pnByte);
          626  +      int *pnKB = va_arg(ap, int *);
          627  +      rc = lsmCheckpointSize(pDb, pnKB);
   563    628         break;
   564    629       }
   565    630   
   566    631       case LSM_INFO_TREE_SIZE: {
   567    632         int *pnOld = va_arg(ap, int *);
   568    633         int *pnNew = va_arg(ap, int *);
   569    634         rc = infoTreeSize(pDb, pnOld, pnNew);
   570    635         break;
   571    636       }
          637  +
          638  +    case LSM_INFO_COMPRESSION_ID: {
          639  +      unsigned int *piOut = va_arg(ap, unsigned int *);
          640  +      if( pDb->pClient ){
          641  +        *piOut = pDb->pClient->iCmpId;
          642  +      }else{
          643  +        rc = lsmInfoCompressionId(pDb, piOut);
          644  +      }
          645  +      break;
          646  +    }
   572    647   
   573    648       default:
   574    649         rc = LSM_MISUSE;
   575    650         break;
   576    651     }
   577    652   
   578    653     va_end(ap);
................................................................................
   677    752   /*
   678    753   ** Open a new cursor handle. 
   679    754   **
   680    755   ** If there are currently no other open cursor handles, and no open write
   681    756   ** transaction, open a read transaction here.
   682    757   */
   683    758   int lsm_csr_open(lsm_db *pDb, lsm_cursor **ppCsr){
   684         -  int rc;                         /* Return code */
          759  +  int rc = LSM_OK;                /* Return code */
   685    760     MultiCursor *pCsr = 0;          /* New cursor object */
   686    761   
   687    762     /* Open a read transaction if one is not already open. */
   688    763     assert_db_state(pDb);
   689         -  rc = lsmBeginReadTrans(pDb);
          764  +
          765  +  if( pDb->pShmhdr==0 ){
          766  +    assert( pDb->bReadonly );
          767  +    rc = lsmBeginRoTrans(pDb);
          768  +  }else if( pDb->iReader<0 ){
          769  +    rc = lsmBeginReadTrans(pDb);
          770  +  }
   690    771   
   691    772     /* Allocate the multi-cursor. */
   692         -  if( rc==LSM_OK ) rc = lsmMCursorNew(pDb, &pCsr);
          773  +  if( rc==LSM_OK ){
          774  +    rc = lsmMCursorNew(pDb, &pCsr);
          775  +  }
   693    776   
   694    777     /* If an error has occured, set the output to NULL and delete any partially
   695    778     ** allocated cursor. If this means there are no open cursors, release the
   696    779     ** client snapshot.  */
   697    780     if( rc!=LSM_OK ){
   698         -    lsmMCursorClose(pCsr);
          781  +    lsmMCursorClose(pCsr, 0);
   699    782       dbReleaseClientSnapshot(pDb);
   700    783     }
   701    784   
   702    785     assert_db_state(pDb);
   703    786     *ppCsr = (lsm_cursor *)pCsr;
   704    787     return rc;
   705    788   }
................................................................................
   707    790   /*
   708    791   ** Close a cursor opened using lsm_csr_open().
   709    792   */
   710    793   int lsm_csr_close(lsm_cursor *p){
   711    794     if( p ){
   712    795       lsm_db *pDb = lsmMCursorDb((MultiCursor *)p);
   713    796       assert_db_state(pDb);
   714         -    lsmMCursorClose((MultiCursor *)p);
          797  +    lsmMCursorClose((MultiCursor *)p, 1);
   715    798       dbReleaseClientSnapshot(pDb);
   716    799       assert_db_state(pDb);
   717    800     }
   718    801     return LSM_OK;
   719    802   }
   720    803   
   721    804   /*
................................................................................
   785    868       va_end(ap2);
   786    869       pDb->xLog(pDb->pLogCtx, rc, s.z);
   787    870       lsmStringClear(&s);
   788    871     }
   789    872   }
   790    873   
   791    874   int lsm_begin(lsm_db *pDb, int iLevel){
   792         -  int rc = LSM_OK;
          875  +  int rc;
   793    876   
   794    877     assert_db_state( pDb );
          878  +  rc = (pDb->bReadonly ? LSM_READONLY : LSM_OK);
   795    879   
   796    880     /* A value less than zero means open one more transaction. */
   797    881     if( iLevel<0 ) iLevel = pDb->nTransOpen + 1;
   798         -
   799    882     if( iLevel>pDb->nTransOpen ){
   800    883       int i;
   801    884   
   802    885       /* Extend the pDb->aTrans[] array if required. */
   803    886       if( rc==LSM_OK && pDb->nTransAlloc<iLevel ){
   804    887         TransMark *aNew;            /* New allocation */
   805    888         int nByte = sizeof(TransMark) * (iLevel+1);
................................................................................
   836    919     assert_db_state( pDb );
   837    920   
   838    921     /* A value less than zero means close the innermost nested transaction. */
   839    922     if( iLevel<0 ) iLevel = LSM_MAX(0, pDb->nTransOpen - 1);
   840    923   
   841    924     if( iLevel<pDb->nTransOpen ){
   842    925       if( iLevel==0 ){
   843         -      int bAutowork = 0;
   844         -
   845    926         /* Commit the transaction to disk. */
   846    927         if( rc==LSM_OK ) rc = lsmLogCommit(pDb);
   847    928         if( rc==LSM_OK && pDb->eSafety==LSM_SAFETY_FULL ){
   848    929           rc = lsmFsSyncLog(pDb->pFS);
   849    930         }
   850    931         lsmFinishWriteTrans(pDb, (rc==LSM_OK));
   851    932       }

Changes to src/lsm_shared.c.

    45     45     /* Protected by the global mutex (enterGlobalMutex/leaveGlobalMutex): */
    46     46     char *zName;                    /* Canonical path to database file */
    47     47     int nName;                      /* strlen(zName) */
    48     48     int nDbRef;                     /* Number of associated lsm_db handles */
    49     49     Database *pDbNext;              /* Next Database structure in global list */
    50     50   
    51     51     /* Protected by the local mutex (pClientMutex) */
           52  +  int bReadonly;                  /* True if Database.pFile is read-only */
    52     53     int bMultiProc;                 /* True if running in multi-process mode */
    53     54     lsm_file *pFile;                /* Used for locks/shm in multi-proc mode */
    54     55     LsmFile *pLsmFile;              /* List of deferred closes */
    55     56     lsm_mutex *pClientMutex;        /* Protects the apShmChunk[] and pConn */
    56     57     int nShmChunk;                  /* Number of entries in apShmChunk[] array */
    57     58     void **apShmChunk;              /* Array of "shared" memory regions */
    58     59     lsm_db *pConn;                  /* List of connections to this db. */
................................................................................
   207    208   ** to as small a size as possible without truncating away any blocks that
   208    209   ** contain data.
   209    210   */
   210    211   static int dbTruncateFile(lsm_db *pDb){
   211    212     int rc;
   212    213   
   213    214     assert( pDb->pWorker==0 );
   214         -  assert( lsmShmAssertLock(pDb, LSM_LOCK_DMS2, LSM_LOCK_EXCL) );
          215  +  assert( lsmShmAssertLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_EXCL) );
   215    216     rc = lsmCheckpointLoadWorker(pDb);
   216    217   
   217    218     if( rc==LSM_OK ){
   218    219       DbTruncateCtx ctx;
   219    220   
   220    221       /* Walk the database free-block-list in reverse order. Set ctx.nBlock
   221    222       ** to the block number of the last block in the database that actually
................................................................................
   237    238     pDb->pWorker = 0;
   238    239     return rc;
   239    240   }
   240    241   
   241    242   static void doDbDisconnect(lsm_db *pDb){
   242    243     int rc;
   243    244   
   244         -  /* Block for an exclusive lock on DMS1. This lock serializes all calls
   245         -  ** to doDbConnect() and doDbDisconnect() across all processes.  */
   246         -  rc = lsmShmLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_EXCL, 1);
   247         -  if( rc==LSM_OK ){
   248         -
   249         -    /* Try an exclusive lock on DMS2. If successful, this is the last
   250         -    ** connection to the database. In this case flush the contents of the
   251         -    ** in-memory tree to disk and write a checkpoint.  */
   252         -    rc = lsmShmLock(pDb, LSM_LOCK_DMS2, LSM_LOCK_EXCL, 0);
          245  +  if( pDb->bReadonly ){
          246  +    lsmShmLock(pDb, LSM_LOCK_DMS3, LSM_LOCK_UNLOCK, 0);
          247  +  }else{
          248  +    /* Block for an exclusive lock on DMS1. This lock serializes all calls
          249  +    ** to doDbConnect() and doDbDisconnect() across all processes.  */
          250  +    rc = lsmShmLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_EXCL, 1);
   253    251       if( rc==LSM_OK ){
   254         -      /* Flush the in-memory tree, if required. If there is data to flush,
   255         -      ** this will create a new client snapshot in Database.pClient. The
   256         -      ** checkpoint (serialization) of this snapshot may be written to disk
   257         -      ** by the following block.  
   258         -      **
   259         -      ** There is no need to mess around with WRITER locks or anything at
   260         -      ** this point. The lock on DMS2 guarantees that pDb has exclusive
   261         -      ** access to the db at this point.
   262         -      */
   263         -      rc = lsmTreeLoadHeader(pDb, 0);
   264         -      if( rc==LSM_OK && (lsmTreeHasOld(pDb) || lsmTreeSize(pDb)>0) ){
   265         -        rc = lsmFlushTreeToDisk(pDb);
   266         -      }
   267         -
   268         -      /* Write a checkpoint to disk. */
   269         -      if( rc==LSM_OK ){
   270         -        rc = lsmCheckpointWrite(pDb, 1, 0);
   271         -      }
   272         -
   273         -      /* If the checkpoint was written successfully, delete the log file
   274         -      ** and, if possible, truncate the database file.  */
   275         -      if( rc==LSM_OK ){
   276         -        Database *p = pDb->pDatabase;
   277         -        dbTruncateFile(pDb);
   278         -        lsmFsCloseAndDeleteLog(pDb->pFS);
   279         -        if( p->pFile && p->bMultiProc ) lsmEnvShmUnmap(pDb->pEnv, p->pFile, 1);
   280         -      }
   281         -    }
   282         -  }
   283         -
   284         -  lsmShmLock(pDb, LSM_LOCK_DMS2, LSM_LOCK_UNLOCK, 0);
   285         -  lsmShmLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_UNLOCK, 0);
          252  +
          253  +      /* Try an exclusive lock on DMS2. If successful, this is the last
          254  +      ** connection to the database. In this case flush the contents of the
          255  +      ** in-memory tree to disk and write a checkpoint.  */
          256  +      rc = lsmShmTestLock(pDb, LSM_LOCK_DMS2, 1, LSM_LOCK_EXCL);
          257  +      if( rc==LSM_OK ){
          258  +        rc = lsmShmTestLock(pDb, LSM_LOCK_CHECKPOINTER, 1, LSM_LOCK_EXCL);
          259  +      }
          260  +      if( rc==LSM_OK ){
          261  +        int bReadonly = 0;        /* True if there exist read-only conns. */
          262  +
          263  +        /* Flush the in-memory tree, if required. If there is data to flush,
          264  +        ** this will create a new client snapshot in Database.pClient. The
          265  +        ** checkpoint (serialization) of this snapshot may be written to disk
          266  +        ** by the following block.  
          267  +        **
          268  +        ** There is no need to take a WRITER lock here. That there are no 
          269  +        ** other locks on DMS2 guarantees that there are no other read-write
          270  +        ** connections at this time (and the lock on DMS1 guarantees that
          271  +        ** no new ones may appear).
          272  +        */
          273  +        rc = lsmTreeLoadHeader(pDb, 0);
          274  +        if( rc==LSM_OK && (lsmTreeHasOld(pDb) || lsmTreeSize(pDb)>0) ){
          275  +          rc = lsmFlushTreeToDisk(pDb);
          276  +        }
          277  +
          278  +        /* Now check if there are any read-only connections. If there are,
          279  +        ** then do not truncate the db file or unlink the shared-memory 
          280  +        ** region.  */
          281  +        if( rc==LSM_OK ){
          282  +          rc = lsmShmTestLock(pDb, LSM_LOCK_DMS3, 1, LSM_LOCK_EXCL);
          283  +          if( rc==LSM_BUSY ){
          284  +            bReadonly = 1;
          285  +            rc = LSM_OK;
          286  +          }
          287  +        }
          288  +
          289  +        /* Write a checkpoint to disk. */
          290  +        if( rc==LSM_OK ){
          291  +          rc = lsmCheckpointWrite(pDb, (bReadonly==0), 0);
          292  +        }
          293  +
          294  +        /* If the checkpoint was written successfully, delete the log file
          295  +        ** and, if possible, truncate the database file.  */
          296  +        if( rc==LSM_OK ){
          297  +          int bRotrans = 0;
          298  +          Database *p = pDb->pDatabase;
          299  +
          300  +          /* The log file may only be deleted if there are no clients 
          301  +          ** read-only clients running rotrans transactions.  */
          302  +          rc = lsmDetectRoTrans(pDb, &bRotrans);
          303  +          if( rc==LSM_OK && bRotrans==0 ){
          304  +            lsmFsCloseAndDeleteLog(pDb->pFS);
          305  +          }
          306  +
          307  +          /* The database may only be truncated if there exist no read-only
          308  +          ** clients - either connected or running rotrans transactions. */
          309  +          if( bReadonly==0 && bRotrans==0 ){
          310  +            dbTruncateFile(pDb);
          311  +            if( p->pFile && p->bMultiProc ){
          312  +              lsmEnvShmUnmap(pDb->pEnv, p->pFile, 1);
          313  +            }
          314  +          }
          315  +        }
          316  +      }
          317  +    }
          318  +
          319  +    if( pDb->iRwclient>=0 ){
          320  +      lsmShmLock(pDb, LSM_LOCK_RWCLIENT(pDb->iRwclient), LSM_LOCK_UNLOCK, 0);
          321  +      pDb->iRwclient = -1;
          322  +    }
          323  +
          324  +    lsmShmLock(pDb, LSM_LOCK_DMS2, LSM_LOCK_UNLOCK, 0);
          325  +    lsmShmLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_UNLOCK, 0);
          326  +  }
   286    327     pDb->pShmhdr = 0;
   287    328   }
   288    329   
   289    330   static int doDbConnect(lsm_db *pDb){
   290    331     const int nUsMax = 100000;      /* Max value for nUs */
   291    332     int nUs = 1000;                 /* us to wait between DMS1 attempts */
   292    333     int rc;
   293    334   
   294    335     /* Obtain a pointer to the shared-memory header */
   295    336     assert( pDb->pShmhdr==0 );
          337  +  assert( pDb->bReadonly==0 );
   296    338     rc = lsmShmCacheChunks(pDb, 1);
   297    339     if( rc!=LSM_OK ) return rc;
   298    340     pDb->pShmhdr = (ShmHeader *)pDb->apShm[0];
   299    341   
   300    342     /* Block for an exclusive lock on DMS1. This lock serializes all calls
   301    343     ** to doDbConnect() and doDbDisconnect() across all processes.  */
   302    344     while( 1 ){
................................................................................
   307    349       if( nUs>nUsMax ) nUs = nUsMax;
   308    350     }
   309    351     if( rc!=LSM_OK ){
   310    352       pDb->pShmhdr = 0;
   311    353       return rc;
   312    354     }
   313    355   
   314         -  /* Try an exclusive lock on DMS2. If successful, this is the first and 
   315         -  ** only connection to the database. In this case initialize the 
          356  +  /* Try an exclusive lock on DMS2/DMS3. If successful, this is the first 
          357  +  ** and only connection to the database. In this case initialize the 
   316    358     ** shared-memory and run log file recovery.  */
   317         -  rc = lsmShmLock(pDb, LSM_LOCK_DMS2, LSM_LOCK_EXCL, 0);
          359  +  assert( LSM_LOCK_DMS3==1+LSM_LOCK_DMS2 );
          360  +  rc = lsmShmTestLock(pDb, LSM_LOCK_DMS2, 2, LSM_LOCK_EXCL);
   318    361     if( rc==LSM_OK ){
   319    362       memset(pDb->pShmhdr, 0, sizeof(ShmHeader));
   320    363       rc = lsmCheckpointRecover(pDb);
   321    364       if( rc==LSM_OK ){
   322    365         rc = lsmLogRecover(pDb);
   323    366       }
          367  +    if( rc==LSM_OK ){
          368  +      ShmHeader *pShm = pDb->pShmhdr;
          369  +      pShm->aReader[0].iLsmId = lsmCheckpointId(pShm->aSnap1, 0);
          370  +      pShm->aReader[0].iTreeId = pDb->treehdr.iUsedShmid;
          371  +    }
   324    372     }else if( rc==LSM_BUSY ){
   325    373       rc = LSM_OK;
   326    374     }
   327    375   
   328    376     /* Take a shared lock on DMS2. In multi-process mode this lock "cannot" 
   329    377     ** fail, as connections may only hold an exclusive lock on DMS2 if they 
   330    378     ** first hold an exclusive lock on DMS1. And this connection is currently 
................................................................................
   334    382     ** mode, this operation will fail. In this case, return the error to the
   335    383     ** caller - the attempt to connect to the db has failed.
   336    384     */
   337    385     if( rc==LSM_OK ){
   338    386       rc = lsmShmLock(pDb, LSM_LOCK_DMS2, LSM_LOCK_SHARED, 0);
   339    387     }
   340    388   
   341         -  /* If anything went wrong, unlock DMS2. Unlock DMS1 in any case. */
          389  +  /* If anything went wrong, unlock DMS2. Otherwise, try to take an exclusive
          390  +  ** lock on one of the LSM_LOCK_RWCLIENT() locks. Unlock DMS1 in any case. */
   342    391     if( rc!=LSM_OK ){
   343         -    lsmShmLock(pDb, LSM_LOCK_DMS2, LSM_LOCK_UNLOCK, 0);
   344    392       pDb->pShmhdr = 0;
          393  +  }else{
          394  +    int i;
          395  +    for(i=0; i<LSM_LOCK_NRWCLIENT; i++){
          396  +      int rc2 = lsmShmLock(pDb, LSM_LOCK_RWCLIENT(i), LSM_LOCK_EXCL, 0);
          397  +      if( rc2==LSM_OK ) pDb->iRwclient = i;
          398  +      if( rc2!=LSM_BUSY ){
          399  +        rc = rc2;
          400  +        break;
          401  +      }
          402  +    }
   345    403     }
   346    404     lsmShmLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_UNLOCK, 0);
          405  +
          406  +  return rc;
          407  +}
          408  +
          409  +static int dbOpenSharedFd(lsm_env *pEnv, Database *p, int bRoOk){
          410  +  int rc;
          411  +
          412  +  rc = lsmEnvOpen(pEnv, p->zName, 0, &p->pFile);
          413  +  if( rc==LSM_IOERR && bRoOk ){
          414  +    rc = lsmEnvOpen(pEnv, p->zName, LSM_OPEN_READONLY, &p->pFile);
          415  +    p->bReadonly = 1;
          416  +  }
          417  +
   347    418     return rc;
   348    419   }
   349    420   
   350    421   /*
   351    422   ** Return a reference to the shared Database handle for the database 
   352    423   ** identified by canonical path zName. If this is the first connection to
   353    424   ** the named database, a new Database object is allocated. Otherwise, a
................................................................................
   394    465           rc = lsmMutexNew(pEnv, &p->pClientMutex);
   395    466         }
   396    467   
   397    468         /* If nothing has gone wrong so far, open the shared fd. And if that
   398    469         ** succeeds and this connection requested single-process mode, 
   399    470         ** attempt to take the exclusive lock on DMS2.  */
   400    471         if( rc==LSM_OK ){
   401         -        rc = lsmEnvOpen(pDb->pEnv, p->zName, &p->pFile);
          472  +        int bReadonly = (pDb->bReadonly && pDb->bMultiProc);
          473  +        rc = dbOpenSharedFd(pDb->pEnv, p, bReadonly);
   402    474         }
          475  +
   403    476         if( rc==LSM_OK && p->bMultiProc==0 ){
          477  +        assert( p->bReadonly==0 );
   404    478           rc = lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS2, LSM_LOCK_EXCL);
   405    479         }
   406    480   
   407    481         if( rc==LSM_OK ){
   408    482           p->pDbNext = gShared.pDatabase;
   409    483           gShared.pDatabase = p;
   410    484         }else{
................................................................................
   425    499         lsmMutexLeave(pDb->pEnv, p->pClientMutex);
   426    500       }
   427    501     }
   428    502   
   429    503     pDb->pDatabase = p;
   430    504     if( rc==LSM_OK ){
   431    505       assert( p );
   432         -    rc = lsmFsOpen(pDb, zName);
          506  +    rc = lsmFsOpen(pDb, zName, p->bReadonly);
   433    507     }
   434         -  if( rc==LSM_OK ){
   435         -    rc = doDbConnect(pDb);
          508  +
          509  +  /* If the db handle is read-write, then connect to the system now. Run
          510  +  ** recovery as necessary. Or, if this is a read-only database handle,
          511  +  ** defer attempting to connect to the system until a read-transaction
          512  +  ** is opened.  */
          513  +  if( pDb->bReadonly==0 ){
          514  +    if( rc==LSM_OK ){
          515  +      rc = doDbConnect(pDb);
          516  +    }
          517  +    if( rc==LSM_OK ){
          518  +      rc = lsmFsConfigure(pDb);
          519  +    }
   436    520     }
   437    521   
   438    522     return rc;
   439    523   }
   440    524   
   441    525   static void dbDeferClose(lsm_db *pDb){
   442    526     if( pDb->pFS ){
................................................................................
   719    803       lsmLogMessage(pDb, 0, "lsmBlockAllocate(): "
   720    804           "snapshot-in-use: %lld (iSynced=%lld) (client-id=%lld)", 
   721    805           iInUse, iSynced, (pDb->iReader>=0 ? pDb->pClient->iId : 0)
   722    806       );
   723    807     }
   724    808   #endif
   725    809   
   726         -  /* Query the free block list for a suitable block */
   727         -  if( rc==LSM_OK ) rc = findFreeblock(pDb, iInUse, (iBefore>0), &iRet);
          810  +
          811  +  /* Unless there exists a read-only transaction (which prevents us from
          812  +  ** recycling any blocks regardless, query the free block list for a 
          813  +  ** suitable block to reuse. 
          814  +  **
          815  +  ** It might seem more natural to check for a read-only transaction at
          816  +  ** the start of this function. However, it is better do wait until after
          817  +  ** the call to lsmCheckpointSynced() to do so.
          818  +  */
          819  +  if( rc==LSM_OK ){
          820  +    int bRotrans;
          821  +    rc = lsmDetectRoTrans(pDb, &bRotrans);
          822  +
          823  +    if( rc==LSM_OK && bRotrans==0 ){
          824  +      rc = findFreeblock(pDb, iInUse, (iBefore>0), &iRet);
          825  +    }
          826  +  }
   728    827   
   729    828     if( iBefore>0 && (iRet<=0 || iRet>=iBefore) ){
   730    829       iRet = 0;
   731    830   
   732    831     }else if( rc==LSM_OK ){
   733    832       /* If a block was found in the free block list, use it and remove it from 
   734    833       ** the list. Otherwise, if no suitable block was found, allocate one from
................................................................................
   781    880   ** but then not used. This function is used to push the block back onto
   782    881   ** the freelist. Refreeing a block is different from freeing is, as a refreed
   783    882   ** block may be reused immediately. Whereas a freed block can not be reused 
   784    883   ** until (at least) after the next checkpoint.
   785    884   */
   786    885   int lsmBlockRefree(lsm_db *pDb, int iBlk){
   787    886     int rc = LSM_OK;                /* Return code */
   788         -  Snapshot *p = pDb->pWorker;
   789    887   
   790    888   #ifdef LSM_LOG_FREELIST
   791    889     lsmLogMessage(pDb, LSM_OK, "lsmBlockRefree(): Refree block %d", iBlk);
   792    890   #endif
   793    891   
   794    892     rc = freelistAppend(pDb, iBlk, 0);
   795    893     return rc;
................................................................................
   887    985     if( p ){
   888    986       lsmSortedFreeLevel(pEnv, p->pLevel);
   889    987       lsmFree(pEnv, p->freelist.aEntry);
   890    988       lsmFree(pEnv, p->redirect.a);
   891    989       lsmFree(pEnv, p);
   892    990     }
   893    991   }
          992  +
          993  +/*
          994  +** Attempt to populate one of the read-lock slots to contain lock values
          995  +** iLsm/iShm. Or, if such a slot exists already, this function is a no-op.
          996  +**
          997  +** It is not an error if no slot can be populated because the write-lock
          998  +** cannot be obtained. If any other error occurs, return an LSM error code.
          999  +** Otherwise, LSM_OK.
         1000  +**
         1001  +** This function is called at various points to try to ensure that there
         1002  +** always exists at least one read-lock slot that can be used by a read-only
         1003  +** client. And so that, in the usual case, there is an "exact match" available
         1004  +** whenever a read transaction is opened by any client. At present this
         1005  +** function is called when:
         1006  +**
         1007  +**    * A write transaction that called lsmTreeDiscardOld() is committed, and
         1008  +**    * Whenever the working snapshot is updated (i.e. lsmFinishWork()).
         1009  +*/
         1010  +static int dbSetReadLock(lsm_db *db, i64 iLsm, u32 iShm){
         1011  +  int rc = LSM_OK;
         1012  +  ShmHeader *pShm = db->pShmhdr;
         1013  +  int i;
         1014  +
         1015  +  /* Check if there is already a slot containing the required values. */
         1016  +  for(i=0; i<LSM_LOCK_NREADER; i++){
         1017  +    ShmReader *p = &pShm->aReader[i];
         1018  +    if( p->iLsmId==iLsm && p->iTreeId==iShm ) return LSM_OK;
         1019  +  }
         1020  +
         1021  +  /* Iterate through all read-lock slots, attempting to take a write-lock
         1022  +  ** on each of them. If a write-lock succeeds, populate the locked slot
         1023  +  ** with the required values and break out of the loop.  */
         1024  +  for(i=0; rc==LSM_OK && i<LSM_LOCK_NREADER; i++){
         1025  +    rc = lsmShmLock(db, LSM_LOCK_READER(i), LSM_LOCK_EXCL, 0);
         1026  +    if( rc==LSM_BUSY ){
         1027  +      rc = LSM_OK;
         1028  +    }else{
         1029  +      ShmReader *p = &pShm->aReader[i];
         1030  +      p->iLsmId = iLsm;
         1031  +      p->iTreeId = iShm;
         1032  +      lsmShmLock(db, LSM_LOCK_READER(i), LSM_LOCK_UNLOCK, 0);
         1033  +      break;
         1034  +    }
         1035  +  }
         1036  +
         1037  +  return rc;
         1038  +}
         1039  +
         1040  +/*
         1041  +** Release the read-lock currently held by connection db.
         1042  +*/
         1043  +int dbReleaseReadlock(lsm_db *db){
         1044  +  int rc = LSM_OK;
         1045  +  if( db->iReader>=0 ){
         1046  +    rc = lsmShmLock(db, LSM_LOCK_READER(db->iReader), LSM_LOCK_UNLOCK, 0);
         1047  +    db->iReader = -1;
         1048  +  }
         1049  +  db->bRoTrans = 0;
         1050  +  return rc;
         1051  +}
         1052  +
   894   1053   
   895   1054   /*
   896   1055   ** Argument bFlush is true if the contents of the in-memory tree has just
   897   1056   ** been flushed to disk. The significance of this is that once the snapshot
   898   1057   ** created to hold the updated state of the database is synced to disk, log
   899   1058   ** file space can be recycled.
   900   1059   */
   901   1060   void lsmFinishWork(lsm_db *pDb, int bFlush, int *pRc){
   902         -  assert( *pRc!=0 || pDb->pWorker );
         1061  +  int rc = *pRc;
         1062  +  assert( rc!=0 || pDb->pWorker );
   903   1063     if( pDb->pWorker ){
   904   1064       /* If no error has occurred, serialize the worker snapshot and write
   905   1065       ** it to shared memory.  */
   906         -    if( *pRc==LSM_OK ){
   907         -      *pRc = lsmSaveWorker(pDb, bFlush);
         1066  +    if( rc==LSM_OK ){
         1067  +      rc = lsmSaveWorker(pDb, bFlush);
   908   1068       }
         1069  +
         1070  +    /* Assuming no error has occurred, update a read lock slot with the
         1071  +    ** new snapshot id (see comments above function dbSetReadLock()).  */
         1072  +    if( rc==LSM_OK ){
         1073  +      if( pDb->iReader<0 ){
         1074  +        rc = lsmTreeLoadHeader(pDb, 0);
         1075  +      }
         1076  +      if( rc==LSM_OK ){
         1077  +        rc = dbSetReadLock(pDb, pDb->pWorker->iId, pDb->treehdr.iUsedShmid);
         1078  +      }
         1079  +    }
         1080  +
         1081  +    /* Free the snapshot object. */
   909   1082       lsmFreeSnapshot(pDb->pEnv, pDb->pWorker);
   910   1083       pDb->pWorker = 0;
   911   1084     }
   912   1085   
   913   1086     lsmShmLock(pDb, LSM_LOCK_WORKER, LSM_LOCK_UNLOCK, 0);
         1087  +  *pRc = rc;
   914   1088   }
   915         -
   916   1089   
   917   1090   /*
   918   1091   ** Called when recovery is finished.
   919   1092   */
   920   1093   int lsmFinishRecovery(lsm_db *pDb){
   921   1094     lsmTreeEndTransaction(pDb, 1);
   922   1095     return LSM_OK;
   923   1096   }
         1097  +
         1098  +/*
         1099  +** Check if the currently configured compression functions
         1100  +** (LSM_CONFIG_SET_COMPRESSION) are compatible with a database that has its
         1101  +** compression id set to iReq. Compression routines are compatible if iReq
         1102  +** is zero (indicating the database is empty), or if it is equal to the 
         1103  +** compression id of the configured compression routines.
         1104  +**
         1105  +** If the check shows that the current compression are incompatible and there
         1106  +** is a compression factory registered, give it a chance to install new
         1107  +** compression routines.
         1108  +**
         1109  +** If, after any registered factory is invoked, the compression functions
         1110  +** are still incompatible, return LSM_MISMATCH. Otherwise, LSM_OK.
         1111  +*/
         1112  +int lsmCheckCompressionId(lsm_db *pDb, u32 iReq){
         1113  +  if( iReq!=LSM_COMPRESSION_EMPTY && pDb->compress.iId!=iReq ){
         1114  +    if( pDb->factory.xFactory ){
         1115  +      pDb->bInFactory = 1;
         1116  +      pDb->factory.xFactory(pDb->factory.pCtx, pDb, iReq);
         1117  +      pDb->bInFactory = 0;
         1118  +    }
         1119  +    if( pDb->compress.iId!=iReq ){
         1120  +      /* Incompatible */
         1121  +      return LSM_MISMATCH;
         1122  +    }
         1123  +  }
         1124  +  /* Compatible */
         1125  +  return LSM_OK;
         1126  +}
   924   1127   
   925   1128   /*
   926   1129   ** Begin a read transaction. This function is a no-op if the connection
   927   1130   ** passed as the only argument already has an open read transaction.
   928   1131   */
   929   1132   int lsmBeginReadTrans(lsm_db *pDb){
   930   1133     const int MAX_READLOCK_ATTEMPTS = 10;
         1134  +  const int nMaxAttempt = (pDb->bRoTrans ? 1 : MAX_READLOCK_ATTEMPTS);
         1135  +
   931   1136     int rc = LSM_OK;                /* Return code */
   932   1137     int iAttempt = 0;
   933   1138   
   934   1139     assert( pDb->pWorker==0 );
   935   1140   
   936         -  while( rc==LSM_OK && pDb->iReader<0 && (iAttempt++)<MAX_READLOCK_ATTEMPTS ){
         1141  +  while( rc==LSM_OK && pDb->iReader<0 && (iAttempt++)<nMaxAttempt ){
   937   1142       int iTreehdr = 0;
   938   1143       int iSnap = 0;
   939   1144       assert( pDb->pCsr==0 && pDb->nTransOpen==0 );
   940   1145   
   941   1146       /* Load the in-memory tree header. */
   942   1147       rc = lsmTreeLoadHeader(pDb, &iTreehdr);
   943   1148   
   944   1149       /* Load the database snapshot */
   945   1150       if( rc==LSM_OK ){
   946   1151         if( lsmCheckpointClientCacheOk(pDb)==0 ){
   947   1152           lsmFreeSnapshot(pDb->pEnv, pDb->pClient);
   948   1153           pDb->pClient = 0;
         1154  +        lsmMCursorFreeCache(pDb);
   949   1155           rc = lsmCheckpointLoad(pDb, &iSnap);
   950   1156         }else{
   951   1157           iSnap = 1;
   952   1158         }
   953   1159       }
   954   1160   
   955   1161       /* Take a read-lock on the tree and snapshot just loaded. Then check
................................................................................
   971   1177             ** lsm_sorted.c is changed to work directly from the serialized
   972   1178             ** version of the snapshot.  */
   973   1179             if( pDb->pClient==0 ){
   974   1180               rc = lsmCheckpointDeserialize(pDb, 0, pDb->aSnapshot,&pDb->pClient);
   975   1181             }
   976   1182             assert( (rc==LSM_OK)==(pDb->pClient!=0) );
   977   1183             assert( pDb->iReader>=0 );
         1184  +
         1185  +          /* Check that the client has the right compression hooks loaded.
         1186  +          ** If not, set rc to LSM_MISMATCH.  */
         1187  +          if( rc==LSM_OK ){
         1188  +            rc = lsmCheckCompressionId(pDb, pDb->pClient->iCmpId);
         1189  +          }
   978   1190           }else{
   979         -          rc = lsmReleaseReadlock(pDb);
         1191  +          rc = dbReleaseReadlock(pDb);
   980   1192           }
   981   1193         }
         1194  +
   982   1195         if( rc==LSM_BUSY ){
   983   1196           rc = LSM_OK;
   984   1197         }
   985   1198       }
   986   1199   #if 0
   987   1200   if( rc==LSM_OK && pDb->pClient ){
   988   1201     fprintf(stderr, 
................................................................................
   996   1209   #endif
   997   1210     }
   998   1211   
   999   1212     if( rc==LSM_OK ){
  1000   1213       rc = lsmShmCacheChunks(pDb, pDb->treehdr.nChunk);
  1001   1214     }
  1002   1215     if( rc!=LSM_OK ){
  1003         -    lsmReleaseReadlock(pDb);
         1216  +    dbReleaseReadlock(pDb);
  1004   1217     }
  1005   1218     if( pDb->pClient==0 && rc==LSM_OK ) rc = LSM_BUSY;
         1219  +  return rc;
         1220  +}
         1221  +
         1222  +/*
         1223  +** This function is used by a read-write connection to determine if there
         1224  +** are currently one or more read-only transactions open on the database
         1225  +** (in this context a read-only transaction is one opened by a read-only
         1226  +** connection on a non-live database).
         1227  +**
         1228  +** If no error occurs, LSM_OK is returned and *pbExists is set to true if
         1229  +** some other connection has a read-only transaction open, or false 
         1230  +** otherwise. If an error occurs an LSM error code is returned and the final
         1231  +** value of *pbExist is undefined.
         1232  +*/
         1233  +int lsmDetectRoTrans(lsm_db *db, int *pbExist){
         1234  +  int rc;
         1235  +
         1236  +  /* Only a read-write connection may use this function. */
         1237  +  assert( db->bReadonly==0 );
         1238  +
         1239  +  rc = lsmShmTestLock(db, LSM_LOCK_ROTRANS, 1, LSM_LOCK_EXCL);
         1240  +  if( rc==LSM_BUSY ){
         1241  +    *pbExist = 1;
         1242  +    rc = LSM_OK;
         1243  +  }else{
         1244  +    *pbExist = 0;
         1245  +  }
         1246  +
         1247  +  return rc;
         1248  +}
         1249  +
         1250  +/*
         1251  +** db is a read-only database handle in the disconnected state. This function
         1252  +** attempts to open a read-transaction on the database. This may involve
         1253  +** connecting to the database system (opening shared memory etc.).
         1254  +*/
         1255  +int lsmBeginRoTrans(lsm_db *db){
         1256  +  int rc = LSM_OK;
         1257  +
         1258  +  assert( db->bReadonly && db->pShmhdr==0 );
         1259  +  assert( db->iReader<0 );
         1260  +
         1261  +  if( db->bRoTrans==0 ){
         1262  +
         1263  +    /* Attempt a shared-lock on DMS1. */
         1264  +    rc = lsmShmLock(db, LSM_LOCK_DMS1, LSM_LOCK_SHARED, 0);
         1265  +    if( rc!=LSM_OK ) return rc;
         1266  +
         1267  +    rc = lsmShmTestLock(
         1268  +        db, LSM_LOCK_RWCLIENT(0), LSM_LOCK_NREADER, LSM_LOCK_SHARED
         1269  +    );
         1270  +    if( rc==LSM_OK ){
         1271  +      /* System is not live. Take a SHARED lock on the ROTRANS byte and
         1272  +      ** release DMS1. Locking ROTRANS tells all read-write clients that they
         1273  +      ** may not recycle any disk space from within the database or log files,
         1274  +      ** as a read-only client may be using it.  */
         1275  +      rc = lsmShmLock(db, LSM_LOCK_ROTRANS, LSM_LOCK_SHARED, 0);
         1276  +      lsmShmLock(db, LSM_LOCK_DMS1, LSM_LOCK_UNLOCK, 0);
         1277  +
         1278  +      if( rc==LSM_OK ){
         1279  +        db->bRoTrans = 1;
         1280  +        rc = lsmShmCacheChunks(db, 1);
         1281  +        if( rc==LSM_OK ){
         1282  +          db->pShmhdr = (ShmHeader *)db->apShm[0];
         1283  +          memset(db->pShmhdr, 0, sizeof(ShmHeader));
         1284  +          rc = lsmCheckpointRecover(db);
         1285  +          if( rc==LSM_OK ){
         1286  +            rc = lsmLogRecover(db);
         1287  +          }
         1288  +        }
         1289  +      }
         1290  +    }else if( rc==LSM_BUSY ){
         1291  +      /* System is live! */
         1292  +      rc = lsmShmLock(db, LSM_LOCK_DMS3, LSM_LOCK_SHARED, 0);
         1293  +      lsmShmLock(db, LSM_LOCK_DMS1, LSM_LOCK_UNLOCK, 0);
         1294  +      if( rc==LSM_OK ){
         1295  +        rc = lsmShmCacheChunks(db, 1);
         1296  +        if( rc==LSM_OK ){
         1297  +          db->pShmhdr = (ShmHeader *)db->apShm[0];
         1298  +        }
         1299  +      }
         1300  +    }
         1301  +
         1302  +    if( rc==LSM_OK ){
         1303  +      rc = lsmBeginReadTrans(db);
         1304  +    }
         1305  +  }
         1306  +
  1006   1307     return rc;
  1007   1308   }
  1008   1309   
  1009   1310   /*
  1010   1311   ** Close the currently open read transaction.
  1011   1312   */
  1012   1313   void lsmFinishReadTrans(lsm_db *pDb){
................................................................................
  1014   1315     /* Worker connections should not be closing read transactions. And
  1015   1316     ** read transactions should only be closed after all cursors and write
  1016   1317     ** transactions have been closed. Finally pClient should be non-NULL
  1017   1318     ** only iff pDb->iReader>=0.  */
  1018   1319     assert( pDb->pWorker==0 );
  1019   1320     assert( pDb->pCsr==0 && pDb->nTransOpen==0 );
  1020   1321   
  1021         -#if 0
  1022         -  if( pClient ){
  1023         -    lsmFreeSnapshot(pDb->pEnv, pDb->pClient);
  1024         -    pDb->pClient = 0;
         1322  +  if( pDb->bRoTrans ){
         1323  +    int i;
         1324  +    for(i=0; i<pDb->nShm; i++){
         1325  +      lsmFree(pDb->pEnv, pDb->apShm[i]);
         1326  +    }
         1327  +    lsmFree(pDb->pEnv, pDb->apShm);
         1328  +    pDb->apShm = 0;
         1329  +    pDb->nShm = 0;
         1330  +    pDb->pShmhdr = 0;
         1331  +
         1332  +    lsmShmLock(pDb, LSM_LOCK_ROTRANS, LSM_LOCK_UNLOCK, 0);
  1025   1333     }
  1026         -#endif
  1027         -
  1028         -#if 0
  1029         -if( pDb->pClient && pDb->iReader>=0 ){
  1030         -  fprintf(stderr, 
  1031         -      "finished reading %p: snapshot:%d\n", (void *)pDb, (int)pDb->pClient->iId
  1032         -  );
  1033         -}
  1034         -#endif
  1035         -  if( pDb->iReader>=0 ) lsmReleaseReadlock(pDb);
         1334  +  dbReleaseReadlock(pDb);
  1036   1335   }
  1037   1336   
  1038   1337   /*
  1039   1338   ** Open a write transaction.
  1040   1339   */
  1041   1340   int lsmBeginWriteTrans(lsm_db *pDb){
  1042         -  int rc;                         /* Return code */
         1341  +  int rc = LSM_OK;                /* Return code */
  1043   1342     ShmHeader *pShm = pDb->pShmhdr; /* Shared memory header */
  1044   1343   
  1045   1344     assert( pDb->nTransOpen==0 );
         1345  +  assert( pDb->bDiscardOld==0 );
         1346  +  assert( pDb->bReadonly==0 );
  1046   1347   
  1047   1348     /* If there is no read-transaction open, open one now. */
  1048         -  rc = lsmBeginReadTrans(pDb);
         1349  +  if( pDb->iReader<0 ){
         1350  +    rc = lsmBeginReadTrans(pDb);
         1351  +  }
  1049   1352   
  1050   1353     /* Attempt to take the WRITER lock */
  1051   1354     if( rc==LSM_OK ){
  1052   1355       rc = lsmShmLock(pDb, LSM_LOCK_WRITER, LSM_LOCK_EXCL, 0);
  1053   1356     }
  1054   1357   
  1055   1358     /* If the previous writer failed mid-transaction, run emergency rollback. */
................................................................................
  1073   1376     ** WRITER lock and return an error code.  */
  1074   1377     if( rc==LSM_OK ){
  1075   1378       TreeHeader *p = &pDb->treehdr;
  1076   1379       pShm->bWriter = 1;
  1077   1380       p->root.iTransId++;
  1078   1381       if( lsmTreeHasOld(pDb) && p->iOldLog==pDb->pClient->iLogOff ){
  1079   1382         lsmTreeDiscardOld(pDb);
         1383  +      pDb->bDiscardOld = 1;
  1080   1384       }
  1081   1385     }else{
  1082   1386       lsmShmLock(pDb, LSM_LOCK_WRITER, LSM_LOCK_UNLOCK, 0);
  1083   1387       if( pDb->pCsr==0 ) lsmFinishReadTrans(pDb);
  1084   1388     }
  1085   1389     return rc;
  1086   1390   }
................................................................................
  1105   1409     lsmLogEnd(pDb, bCommit);
  1106   1410     if( rc==LSM_OK && bCommit && lsmTreeSize(pDb)>pDb->nTreeLimit ){
  1107   1411       bFlush = 1;
  1108   1412       lsmTreeMakeOld(pDb);
  1109   1413     }
  1110   1414     lsmTreeEndTransaction(pDb, bCommit);
  1111   1415   
  1112         -  if( rc==LSM_OK && bFlush && pDb->bAutowork ){
  1113         -    rc = lsmSortedAutoWork(pDb, 1);
         1416  +  if( rc==LSM_OK ){
         1417  +    if( bFlush && pDb->bAutowork ){
         1418  +      rc = lsmSortedAutoWork(pDb, 1);
         1419  +    }else if( bCommit && pDb->bDiscardOld ){
         1420  +      rc = dbSetReadLock(pDb, pDb->pClient->iId, pDb->treehdr.iUsedShmid);
         1421  +    }
  1114   1422     }
         1423  +  pDb->bDiscardOld = 0;
  1115   1424     lsmShmLock(pDb, LSM_LOCK_WRITER, LSM_LOCK_UNLOCK, 0);
         1425  +
  1116   1426     if( bFlush && pDb->bAutowork==0 && pDb->xWork ){
  1117   1427       pDb->xWork(pDb, pDb->pWorkCtx);
  1118   1428     }
  1119   1429     return rc;
  1120   1430   }
  1121   1431   
  1122   1432   
................................................................................
  1145   1455   int lsmReadlock(lsm_db *db, i64 iLsm, u32 iShmMin, u32 iShmMax){
  1146   1456     int rc = LSM_OK;
  1147   1457     ShmHeader *pShm = db->pShmhdr;
  1148   1458     int i;
  1149   1459   
  1150   1460     assert( db->iReader<0 );
  1151   1461     assert( shm_sequence_ge(iShmMax, iShmMin) );
         1462  +
         1463  +  /* This is a no-op if the read-only transaction flag is set. */
         1464  +  if( db->bRoTrans ){
         1465  +    db->iReader = 0;
         1466  +    return LSM_OK;
         1467  +  }
  1152   1468   
  1153   1469     /* Search for an exact match. */
  1154   1470     for(i=0; db->iReader<0 && rc==LSM_OK && i<LSM_LOCK_NREADER; i++){
  1155   1471       ShmReader *p = &pShm->aReader[i];
  1156   1472       if( p->iLsmId==iLsm && p->iTreeId==iShmMax ){
  1157   1473         rc = lsmShmLock(db, LSM_LOCK_READER(i), LSM_LOCK_SHARED, 0);
  1158   1474         if( rc==LSM_OK && p->iLsmId==iLsm && p->iTreeId==iShmMax ){
................................................................................
  1288   1604     if( db->pClient && db->pClient->iId<=iLsmId ){
  1289   1605       *pbInUse = 1;
  1290   1606       return LSM_OK;
  1291   1607     }
  1292   1608     return isInUse(db, iLsmId, 0, pbInUse);
  1293   1609   }
  1294   1610   
  1295         -/*
  1296         -** Release the read-lock currently held by connection db.
  1297         -*/
  1298         -int lsmReleaseReadlock(lsm_db *db){
  1299         -  int rc = LSM_OK;
  1300         -  if( db->iReader>=0 ){
  1301         -    rc = lsmShmLock(db, LSM_LOCK_READER(db->iReader), LSM_LOCK_UNLOCK, 0);
  1302         -    db->iReader = -1;
  1303         -  }
  1304         -  return rc;
  1305         -}
  1306         -
  1307   1611   /*
  1308   1612   ** This function may only be called after a successful call to
  1309   1613   ** lsmDbDatabaseConnect(). It returns true if the connection is in
  1310   1614   ** multi-process mode, or false otherwise.
  1311   1615   */
  1312   1616   int lsmDbMultiProc(lsm_db *pDb){
  1313   1617     return pDb->pDatabase && pDb->pDatabase->bMultiProc;
................................................................................
  1325   1629   ** Ensure that database connection db has cached pointers to at least the 
  1326   1630   ** first nChunk chunks of shared memory.
  1327   1631   */
  1328   1632   int lsmShmCacheChunks(lsm_db *db, int nChunk){
  1329   1633     int rc = LSM_OK;
  1330   1634     if( nChunk>db->nShm ){
  1331   1635       static const int NINCR = 16;
  1332         -    void *pRet = 0;
  1333   1636       Database *p = db->pDatabase;
  1334   1637       lsm_env *pEnv = db->pEnv;
  1335   1638       int nAlloc;
  1336   1639       int i;
  1337   1640   
  1338   1641       /* Ensure that the db->apShm[] array is large enough. If an attempt to
  1339   1642       ** allocate memory fails, return LSM_NOMEM immediately. The apShm[] array
................................................................................
  1344   1647         void **apShm;
  1345   1648         nAlloc += NINCR;
  1346   1649         apShm = lsmRealloc(pEnv, db->apShm, sizeof(void*)*nAlloc);
  1347   1650         if( !apShm ) return LSM_NOMEM_BKPT;
  1348   1651         db->apShm = apShm;
  1349   1652       }
  1350   1653   
  1351         -    /* Enter the client mutex */
  1352         -    lsmMutexEnter(pEnv, p->pClientMutex);
         1654  +    if( db->bRoTrans ){
         1655  +      for(i=db->nShm; rc==LSM_OK && i<nChunk; i++){
         1656  +        db->apShm[i] = lsmMallocZeroRc(pEnv, LSM_SHM_CHUNK_SIZE, &rc);
         1657  +        db->nShm++;
         1658  +      }
  1353   1659   
  1354         -    /* Extend the Database objects apShmChunk[] array if necessary. Using the
  1355         -    ** same pattern as for the lsm_db.apShm[] array above.  */
  1356         -    nAlloc = ((p->nShmChunk + NINCR - 1) / NINCR) * NINCR;
  1357         -    while( nChunk>=nAlloc ){
  1358         -      void **apShm;
  1359         -      nAlloc +=  NINCR;
  1360         -      apShm = lsmRealloc(pEnv, p->apShmChunk, sizeof(void*)*nAlloc);
  1361         -      if( !apShm ){
  1362         -        rc = LSM_NOMEM_BKPT;
  1363         -        break;
         1660  +    }else{
         1661  +
         1662  +      /* Enter the client mutex */
         1663  +      lsmMutexEnter(pEnv, p->pClientMutex);
         1664  +
         1665  +      /* Extend the Database objects apShmChunk[] array if necessary. Using the
         1666  +       ** same pattern as for the lsm_db.apShm[] array above.  */
         1667  +      nAlloc = ((p->nShmChunk + NINCR - 1) / NINCR) * NINCR;
         1668  +      while( nChunk>=nAlloc ){
         1669  +        void **apShm;
         1670  +        nAlloc +=  NINCR;
         1671  +        apShm = lsmRealloc(pEnv, p->apShmChunk, sizeof(void*)*nAlloc);
         1672  +        if( !apShm ){
         1673  +          rc = LSM_NOMEM_BKPT;
         1674  +          break;
         1675  +        }
         1676  +        p->apShmChunk = apShm;
  1364   1677         }
  1365         -      p->apShmChunk = apShm;
  1366         -    }
  1367   1678   
  1368         -    for(i=db->nShm; rc==LSM_OK && i<nChunk; i++){
  1369         -      if( i>=p->nShmChunk ){
  1370         -        void *pChunk = 0;
  1371         -        if( p->bMultiProc==0 ){
  1372         -          /* Single process mode */
  1373         -          pChunk = lsmMallocZeroRc(pEnv, LSM_SHM_CHUNK_SIZE, &rc);
  1374         -        }else{
  1375         -          /* Multi-process mode */
  1376         -          rc = lsmEnvShmMap(pEnv, p->pFile, i, LSM_SHM_CHUNK_SIZE, &pChunk);
         1679  +      for(i=db->nShm; rc==LSM_OK && i<nChunk; i++){
         1680  +        if( i>=p->nShmChunk ){
         1681  +          void *pChunk = 0;
         1682  +          if( p->bMultiProc==0 ){
         1683  +            /* Single process mode */
         1684  +            pChunk = lsmMallocZeroRc(pEnv, LSM_SHM_CHUNK_SIZE, &rc);
         1685  +          }else{
         1686  +            /* Multi-process mode */
         1687  +            rc = lsmEnvShmMap(pEnv, p->pFile, i, LSM_SHM_CHUNK_SIZE, &pChunk);
         1688  +          }
         1689  +          if( rc==LSM_OK ){
         1690  +            p->apShmChunk[i] = pChunk;
         1691  +            p->nShmChunk++;
         1692  +          }
  1377   1693           }
  1378   1694           if( rc==LSM_OK ){
  1379         -          p->apShmChunk[i] = pChunk;
  1380         -          p->nShmChunk++;
         1695  +          db->apShm[i] = p->apShmChunk[i];
         1696  +          db->nShm++;
  1381   1697           }
  1382   1698         }
  1383         -      if( rc==LSM_OK ){
  1384         -        db->apShm[i] = p->apShmChunk[i];
  1385         -        db->nShm++;
  1386         -      }
         1699  +
         1700  +      /* Release the client mutex */
         1701  +      lsmMutexLeave(pEnv, p->pClientMutex);
  1387   1702       }
  1388         -
  1389         -    /* Release the client mutex */
  1390         -    lsmMutexLeave(pEnv, p->pClientMutex);
  1391   1703     }
  1392   1704   
  1393   1705     return rc;
  1394   1706   }
  1395   1707   
  1396   1708   static int lockSharedFile(lsm_env *pEnv, Database *p, int iLock, int eOp){
  1397   1709     int rc = LSM_OK;
  1398   1710     if( p->bMultiProc ){
  1399   1711       rc = lsmEnvLock(pEnv, p->pFile, iLock, eOp);
  1400   1712     }
  1401   1713     return rc;
  1402   1714   }
         1715  +
         1716  +/*
         1717  +** Test if it would be possible for connection db to obtain a lock of type
         1718  +** eType on the nLock locks starting at iLock. If so, return LSM_OK. If it
         1719  +** would not be possible to obtain the lock due to a lock held by another
         1720  +** connection, return LSM_BUSY. If an IO or other error occurs (i.e. in the 
         1721  +** lsm_env.xTestLock function), return some other LSM error code.
         1722  +**
         1723  +** Note that this function never actually locks the database - it merely
         1724  +** queries the system to see if there exists a lock that would prevent
         1725  +** it from doing so.
         1726  +*/
         1727  +int lsmShmTestLock(
         1728  +  lsm_db *db,
         1729  +  int iLock,
         1730  +  int nLock,
         1731  +  int eOp
         1732  +){
         1733  +  int rc = LSM_OK;
         1734  +  lsm_db *pIter;
         1735  +  Database *p = db->pDatabase;
         1736  +  int i;
         1737  +  u64 mask = 0;
         1738  +
         1739  +  for(i=iLock; i<(iLock+nLock); i++){
         1740  +    mask |= ((u64)1 << (iLock-1));
         1741  +    if( eOp==LSM_LOCK_EXCL ) mask |= ((u64)1 << (iLock+32-1));
         1742  +  }
         1743  +
         1744  +  lsmMutexEnter(db->pEnv, p->pClientMutex);
         1745  +  for(pIter=p->pConn; pIter; pIter=pIter->pNext){
         1746  +    if( pIter!=db && (pIter->mLock & mask) ) break;
         1747  +  }
         1748  +
         1749  +  if( pIter ){
         1750  +    rc = LSM_BUSY;
         1751  +  }else if( p->bMultiProc ){
         1752  +    rc = lsmEnvTestLock(db->pEnv, p->pFile, iLock, nLock, eOp);
         1753  +  }
         1754  +
         1755  +  lsmMutexLeave(db->pEnv, p->pClientMutex);
         1756  +  return rc;
         1757  +}
  1403   1758   
  1404   1759   /*
  1405   1760   ** Attempt to obtain the lock identified by the iLock and bExcl parameters.
  1406   1761   ** If successful, return LSM_OK. If the lock cannot be obtained because 
  1407   1762   ** there exists some other conflicting lock, return LSM_BUSY. If some other
  1408   1763   ** error occurs, return an LSM error code.
  1409   1764   **
................................................................................
  1413   1768   int lsmShmLock(
  1414   1769     lsm_db *db, 
  1415   1770     int iLock,
  1416   1771     int eOp,                        /* One of LSM_LOCK_UNLOCK, SHARED or EXCL */
  1417   1772     int bBlock                      /* True for a blocking lock */
  1418   1773   ){
  1419   1774     lsm_db *pIter;
  1420         -  const u32 me = (1 << (iLock-1));
  1421         -  const u32 ms = (1 << (iLock+16-1));
         1775  +  const u64 me = ((u64)1 << (iLock-1));
         1776  +  const u64 ms = ((u64)1 << (iLock+32-1));
  1422   1777     int rc = LSM_OK;
  1423   1778     Database *p = db->pDatabase;
  1424   1779   
  1425         -  assert( iLock>=1 && iLock<=LSM_LOCK_READER(LSM_LOCK_NREADER-1) );
  1426         -  assert( iLock<=16 );
         1780  +  assert( eOp!=LSM_LOCK_EXCL || db->bReadonly==0 );
         1781  +  assert( iLock>=1 && iLock<=LSM_LOCK_RWCLIENT(LSM_LOCK_NRWCLIENT-1) );
         1782  +  assert( LSM_LOCK_RWCLIENT(LSM_LOCK_NRWCLIENT-1)<=32 );
  1427   1783     assert( eOp==LSM_LOCK_UNLOCK || eOp==LSM_LOCK_SHARED || eOp==LSM_LOCK_EXCL );
  1428   1784   
  1429   1785     /* Check for a no-op. Proceed only if this is not one of those. */
  1430   1786     if( (eOp==LSM_LOCK_UNLOCK && (db->mLock & (me|ms))!=0)
  1431   1787      || (eOp==LSM_LOCK_SHARED && (db->mLock & (me|ms))!=ms)
  1432   1788      || (eOp==LSM_LOCK_EXCL   && (db->mLock & me)==0)
  1433   1789     ){
................................................................................
  1462   1818         case LSM_LOCK_SHARED:
  1463   1819           if( nExcl ){
  1464   1820             rc = LSM_BUSY;
  1465   1821           }else{
  1466   1822             if( nShared==0 ){
  1467   1823               rc = lockSharedFile(db->pEnv, p, iLock, LSM_LOCK_SHARED);
  1468   1824             }
  1469         -          db->mLock |= ms;
  1470         -          db->mLock &= ~me;
         1825  +          if( rc==LSM_OK ){
         1826  +            db->mLock |= ms;
         1827  +            db->mLock &= ~me;
         1828  +          }
  1471   1829           }
  1472   1830           break;
  1473   1831   
  1474   1832         default:
  1475   1833           assert( eOp==LSM_LOCK_EXCL );
  1476   1834           if( nExcl || nShared ){
  1477   1835             rc = LSM_BUSY;
  1478   1836           }else{
  1479   1837             rc = lockSharedFile(db->pEnv, p, iLock, LSM_LOCK_EXCL);
  1480         -          db->mLock |= (me|ms);
         1838  +          if( rc==LSM_OK ){
         1839  +            db->mLock |= (me|ms);
         1840  +          }
  1481   1841           }
  1482   1842           break;
  1483   1843       }
  1484   1844   
  1485   1845       lsmMutexLeave(db->pEnv, p->pClientMutex);
  1486   1846     }
  1487   1847   
  1488   1848     return rc;
  1489   1849   }
  1490   1850   
  1491   1851   #ifdef LSM_DEBUG
  1492   1852   
  1493   1853   int shmLockType(lsm_db *db, int iLock){
  1494         -  const u32 me = (1 << (iLock-1));
  1495         -  const u32 ms = (1 << (iLock+16-1));
         1854  +  const u64 me = ((u64)1 << (iLock-1));
         1855  +  const u64 ms = ((u64)1 << (iLock+32-1));
  1496   1856   
  1497   1857     if( db->mLock & me ) return LSM_LOCK_EXCL;
  1498   1858     if( db->mLock & ms ) return LSM_LOCK_SHARED;
  1499   1859     return LSM_LOCK_UNLOCK;
  1500   1860   }
  1501   1861   
  1502   1862   /*
................................................................................
  1580   1940   }
  1581   1941   #endif
  1582   1942   
  1583   1943   void lsmShmBarrier(lsm_db *db){
  1584   1944     lsmEnvShmBarrier(db->pEnv);
  1585   1945   }
  1586   1946   
  1587         -int lsm_checkpoint(lsm_db *pDb, int *pnByte){
         1947  +int lsm_checkpoint(lsm_db *pDb, int *pnKB){
  1588   1948     int rc;                         /* Return code */
  1589   1949     u32 nWrite = 0;                 /* Number of pages checkpointed */
  1590   1950   
  1591   1951     /* Attempt the checkpoint. If successful, nWrite is set to the number of
  1592   1952     ** pages written between this and the previous checkpoint.  */
  1593   1953     rc = lsmCheckpointWrite(pDb, 0, &nWrite);
  1594   1954   
  1595         -  /* If required, calculate the output variable (bytes of data checkpointed). 
         1955  +  /* If required, calculate the output variable (KB of data checkpointed). 
  1596   1956     ** Set it to zero if an error occured.  */
  1597         -  if( pnByte ){
  1598         -    int nByte = 0;
         1957  +  if( pnKB ){
         1958  +    int nKB = 0;
  1599   1959       if( rc==LSM_OK && nWrite ){
  1600         -      nByte = (int)nWrite * lsmFsPageSize(pDb->pFS);
         1960  +      nKB = (((i64)nWrite * lsmFsPageSize(pDb->pFS)) + 1023) / 1024;
  1601   1961       }
  1602         -    *pnByte = nByte;
         1962  +    *pnKB = nKB;
  1603   1963     }
  1604   1964   
  1605   1965     return rc;
  1606   1966   }
  1607   1967   

Changes to src/lsm_sorted.c.

  2241   2241     pCsr->aTree = 0;
  2242   2242     pCsr->pSystemVal = 0;
  2243   2243     pCsr->apTreeCsr[0] = 0;
  2244   2244     pCsr->apTreeCsr[1] = 0;
  2245   2245     pCsr->pBtCsr = 0;
  2246   2246   }
  2247   2247   
  2248         -void lsmMCursorClose(MultiCursor *pCsr){
         2248  +void lsmMCursorFreeCache(lsm_db *pDb){
         2249  +  MultiCursor *p;
         2250  +  MultiCursor *pNext;
         2251  +  for(p=pDb->pCsrCache; p; p=pNext){
         2252  +    pNext = p->pNext;
         2253  +    lsmMCursorClose(p, 0);
         2254  +  }
         2255  +  pDb->pCsrCache = 0;
         2256  +}
         2257  +
         2258  +/*
         2259  +** Close the cursor passed as the first argument.
         2260  +**
         2261  +** If the bCache parameter is true, then shift the cursor to the pCsrCache
         2262  +** list for possible reuse instead of actually deleting it.
         2263  +*/
         2264  +void lsmMCursorClose(MultiCursor *pCsr, int bCache){
  2249   2265     if( pCsr ){
  2250   2266       lsm_db *pDb = pCsr->pDb;
  2251   2267       MultiCursor **pp;             /* Iterator variable */
  2252   2268   
  2253   2269       /* The cursor may or may not be currently part of the linked list 
  2254   2270       ** starting at lsm_db.pCsr. If it is, extract it.  */
  2255   2271       for(pp=&pDb->pCsr; *pp; pp=&((*pp)->pNext)){
  2256   2272         if( *pp==pCsr ){
  2257   2273           *pp = pCsr->pNext;
  2258   2274           break;
  2259   2275         }
  2260   2276       }
  2261   2277   
  2262         -    /* Free the allocation used to cache the current key, if any. */
  2263         -    sortedBlobFree(&pCsr->key);
  2264         -    sortedBlobFree(&pCsr->val);
         2278  +    if( bCache ){
         2279  +      int i;                      /* Used to iterate through segment-pointers */
  2265   2280   
  2266         -    /* Free the component cursors */
  2267         -    mcursorFreeComponents(pCsr);
         2281  +      /* Release any page references held by this cursor. */
         2282  +      assert( !pCsr->pBtCsr );
         2283  +      for(i=0; i<pCsr->nPtr; i++){
         2284  +        SegmentPtr *pPtr = &pCsr->aPtr[i];
         2285  +        lsmFsPageRelease(pPtr->pPg);
         2286  +        pPtr->pPg = 0;
         2287  +      }
  2268   2288   
  2269         -    /* Free the cursor structure itself */
  2270         -    lsmFree(pDb->pEnv, pCsr);
         2289  +      /* Reset the tree cursors */
         2290  +      lsmTreeCursorReset(pCsr->apTreeCsr[0]);
         2291  +      lsmTreeCursorReset(pCsr->apTreeCsr[1]);
         2292  +
         2293  +      /* Add the cursor to the pCsrCache list */
         2294  +      pCsr->pNext = pDb->pCsrCache;
         2295  +      pDb->pCsrCache = pCsr;
         2296  +    }else{
         2297  +      /* Free the allocation used to cache the current key, if any. */
         2298  +      sortedBlobFree(&pCsr->key);
         2299  +      sortedBlobFree(&pCsr->val);
         2300  +
         2301  +      /* Free the component cursors */
         2302  +      mcursorFreeComponents(pCsr);
         2303  +
         2304  +      /* Free the cursor structure itself */
         2305  +      lsmFree(pDb->pEnv, pCsr);
         2306  +    }
  2271   2307     }
  2272   2308   }
  2273   2309   
  2274   2310   #define TREE_NONE 0
  2275   2311   #define TREE_OLD  1
  2276   2312   #define TREE_BOTH 2
  2277   2313   
................................................................................
  2422   2458     pCsr->flags |= CURSOR_FLUSH_FREELIST;
  2423   2459     pCsr->pSystemVal = lsmMallocRc(pCsr->pDb->pEnv, 4 + 8, &rc);
  2424   2460     return rc;
  2425   2461   }
  2426   2462   
  2427   2463   /*
  2428   2464   ** Allocate and return a new database cursor.
         2465  +**
         2466  +** This method should only be called to allocate user cursors. As it may
         2467  +** recycle a cursor from lsm_db.pCsrCache.
  2429   2468   */
  2430   2469   int lsmMCursorNew(
  2431   2470     lsm_db *pDb,                    /* Database handle */
  2432   2471     MultiCursor **ppCsr             /* OUT: Allocated cursor */
  2433   2472   ){
  2434   2473     MultiCursor *pCsr = 0;
  2435   2474     int rc = LSM_OK;
  2436   2475   
  2437         -  pCsr = multiCursorNew(pDb, &rc);
  2438         -  if( rc==LSM_OK ) rc = multiCursorInit(pCsr, pDb->pClient);
         2476  +  if( pDb->pCsrCache ){
         2477  +    int bOld;                     /* True if there is an old in-memory tree */
         2478  +
         2479  +    /* Remove a cursor from the pCsrCache list and add it to the open list. */
         2480  +    pCsr = pDb->pCsrCache;
         2481  +    pDb->pCsrCache = pCsr->pNext;
         2482  +    pCsr->pNext = pDb->pCsr;
         2483  +    pDb->pCsr = pCsr;
         2484  +
         2485  +    /* The cursor can almost be used as is, except that the old in-memory
         2486  +    ** tree cursor may be present and not required, or required and not
         2487  +    ** present. Fix this if required.  */
         2488  +    bOld = (lsmTreeHasOld(pDb) && pDb->treehdr.iOldLog!=pDb->pClient->iLogOff);
         2489  +    if( !bOld && pCsr->apTreeCsr[1] ){
         2490  +      lsmTreeCursorDestroy(pCsr->apTreeCsr[1]);
         2491  +      pCsr->apTreeCsr[1] = 0;
         2492  +    }else if( bOld && !pCsr->apTreeCsr[1] ){
         2493  +      rc = lsmTreeCursorNew(pDb, 1, &pCsr->apTreeCsr[1]);
         2494  +    }
         2495  +
         2496  +  }else{
         2497  +    pCsr = multiCursorNew(pDb, &rc);
         2498  +    if( rc==LSM_OK ) rc = multiCursorInit(pCsr, pDb->pClient);
         2499  +  }
  2439   2500   
  2440   2501     if( rc!=LSM_OK ){
  2441         -    lsmMCursorClose(pCsr);
         2502  +    lsmMCursorClose(pCsr, 0);
  2442   2503       pCsr = 0;
  2443   2504     }
  2444   2505     assert( (rc==LSM_OK)==(pCsr!=0) );
  2445   2506     *ppCsr = pCsr;
  2446   2507     return rc;
  2447   2508   }
  2448   2509   
................................................................................
  2553   2614           iSnap = (i64)lsmGetU64((u8 *)pVal);
  2554   2615           if( x(pCtx, iBlk, iSnap) ) break;
  2555   2616           rc = multiCursorAdvance(pCsr, !bReverse);
  2556   2617         }
  2557   2618       }
  2558   2619     }
  2559   2620   
  2560         -  lsmMCursorClose(pCsr);
         2621  +  lsmMCursorClose(pCsr, 0);
  2561   2622     if( pSnap!=pDb->pWorker ){
  2562   2623       lsmFreeSnapshot(pDb->pEnv, pSnap);
  2563   2624     }
  2564   2625   
  2565   2626     return rc;
  2566   2627   }
  2567   2628   
................................................................................
  2596   2657           if( *ppVal ){
  2597   2658             memcpy(*ppVal, pVal, nVal);
  2598   2659             *pnVal = nVal;
  2599   2660           }
  2600   2661         }
  2601   2662       }
  2602   2663   
  2603         -    lsmMCursorClose(pCsr);
         2664  +    lsmMCursorClose(pCsr, 0);
  2604   2665     }
  2605   2666   
  2606   2667     return rc;
  2607   2668   }
  2608   2669   
  2609   2670   static int multiCursorAllocTree(MultiCursor *pCsr){
  2610   2671     int rc = LSM_OK;
................................................................................
  4031   4092       }else{
  4032   4093         btreeCursorSplitkey(pCsr->pBtCsr, &pMerge->splitkey);
  4033   4094       }
  4034   4095       
  4035   4096       pMerge->iOutputOff = -1;
  4036   4097     }
  4037   4098   
  4038         -  lsmMCursorClose(pCsr);
         4099  +  lsmMCursorClose(pCsr, 0);
  4039   4100   
  4040   4101     /* Persist and release the output page. */
  4041   4102     if( rc==LSM_OK ) rc = mergeWorkerPersistAndRelease(pMW);
  4042   4103     if( rc==LSM_OK ) rc = mergeWorkerBtreeIndirect(pMW);
  4043   4104     if( rc==LSM_OK ) rc = mergeWorkerFinishHierarchy(pMW);
  4044   4105     if( rc==LSM_OK ) rc = mergeWorkerAddPadding(pMW);
  4045   4106     lsmFsFlushWaiting(pMW->pDb->pFS, &rc);
................................................................................
  4285   4346       ** markers present in the in-memory tree.  */
  4286   4347       if( pNext==0 ){
  4287   4348         multiCursorIgnoreDelete(pCsr);
  4288   4349       }
  4289   4350     }
  4290   4351   
  4291   4352     if( rc!=LSM_OK ){
  4292         -    lsmMCursorClose(pCsr);
         4353  +    lsmMCursorClose(pCsr, 0);
  4293   4354     }else{
  4294   4355       Pgno iLeftPtr = 0;
  4295   4356       Merge merge;                  /* Merge object used to create new level */
  4296   4357       MergeWorker mergeworker;      /* MergeWorker object for the same purpose */
  4297   4358   
  4298   4359       memset(&merge, 0, sizeof(Merge));
  4299   4360       memset(&mergeworker, 0, sizeof(MergeWorker));
................................................................................
  4738   4799     rc = lsmFsMoveBlock(pDb->pFS, &pLvl->lhs, iTo, iFrom);
  4739   4800     if( rc==LSM_OK ){
  4740   4801       if( p->redirect.a==0 ){
  4741   4802         int nByte = sizeof(struct RedirectEntry) * LSM_MAX_BLOCK_REDIRECTS;
  4742   4803         p->redirect.a = lsmMallocZeroRc(pDb->pEnv, nByte, &rc);
  4743   4804       }
  4744   4805       if( rc==LSM_OK ){
  4745         -      memmove(&p->redirect.a[1], &p->redirect.a[0], 
  4746         -          sizeof(struct RedirectEntry) * p->redirect.n
  4747         -      );
  4748         -      p->redirect.a[0].iFrom = iFrom;
  4749         -      p->redirect.a[0].iTo = iTo;
  4750         -      p->redirect.n++;
         4806  +
         4807  +      /* Check if the block just moved was already redirected. */
         4808  +      int i;
         4809  +      for(i=0; i<p->redirect.n; i++){
         4810  +        if( p->redirect.a[i].iTo==iFrom ) break;
         4811  +      }
         4812  +
         4813  +      if( i==p->redirect.n ){
         4814  +        /* Block iFrom was not already redirected. Add a new array entry. */
         4815  +        memmove(&p->redirect.a[1], &p->redirect.a[0], 
         4816  +            sizeof(struct RedirectEntry) * p->redirect.n
         4817  +            );
         4818  +        p->redirect.a[0].iFrom = iFrom;
         4819  +        p->redirect.a[0].iTo = iTo;
         4820  +        p->redirect.n++;
         4821  +      }else{
         4822  +        /* Block iFrom was already redirected. Overwrite existing entry. */
         4823  +        p->redirect.a[i].iTo = iTo;
         4824  +      }
  4751   4825   
  4752   4826         rc = lsmBlockFree(pDb, iFrom);
  4753   4827   
  4754   4828         *pnWrite = lsmFsBlockSize(pDb->pFS) / lsmFsPageSize(pDb->pFS);
  4755   4829         pLvl->lhs.pRedirect = &p->redirect;
  4756   4830       }
  4757   4831     }
................................................................................
  5196   5270   
  5197   5271   static int doLsmWork(lsm_db *pDb, int nMerge, int nPage, int *pnWrite){
  5198   5272     int rc = LSM_OK;                /* Return code */
  5199   5273     int nWrite = 0;                 /* Number of pages written */
  5200   5274   
  5201   5275     assert( nMerge>=1 );
  5202   5276   
  5203         -  if( nPage>0 ){
         5277  +  if( nPage!=0 ){
  5204   5278       int bCkpt = 0;
  5205   5279       do {
  5206   5280         int nThis = 0;
         5281  +      int nReq = (nPage>=0) ? (nPage-nWrite) : ((int)0x7FFFFFFF);
         5282  +
  5207   5283         bCkpt = 0;
  5208         -      rc = doLsmSingleWork(pDb, 0, nMerge, nPage-nWrite, &nThis, &bCkpt);
         5284  +      rc = doLsmSingleWork(pDb, 0, nMerge, nReq, &nThis, &bCkpt);
  5209   5285         nWrite += nThis;
  5210   5286         if( rc==LSM_OK && bCkpt ){
  5211   5287           rc = lsm_checkpoint(pDb, 0);
  5212   5288         }
  5213         -    }while( rc==LSM_OK && (nWrite<nPage && bCkpt) );
         5289  +    }while( rc==LSM_OK && bCkpt && (nWrite<nPage || nPage<0) );
  5214   5290     }
  5215   5291   
  5216   5292     if( pnWrite ){
  5217   5293       if( rc==LSM_OK ){
  5218   5294         *pnWrite = nWrite;
  5219   5295       }else{
  5220   5296         *pnWrite = 0;
................................................................................
  5222   5298     }
  5223   5299     return rc;
  5224   5300   }
  5225   5301   
  5226   5302   /*
  5227   5303   ** Perform work to merge database segments together.
  5228   5304   */
  5229         -int lsm_work(lsm_db *pDb, int nMerge, int nPage, int *pnWrite){
         5305  +int lsm_work(lsm_db *pDb, int nMerge, int nKB, int *pnWrite){
         5306  +  int rc;                         /* Return code */
         5307  +  int nPgsz;                      /* Nominal page size in bytes */
         5308  +  int nPage;                      /* Equivalent of nKB in pages */
         5309  +  int nWrite = 0;                 /* Number of pages written */
  5230   5310   
  5231   5311     /* This function may not be called if pDb has an open read or write
  5232   5312     ** transaction. Return LSM_MISUSE if an application attempts this.  */
  5233   5313     if( pDb->nTransOpen || pDb->pCsr ) return LSM_MISUSE_BKPT;
  5234         -
  5235   5314     if( nMerge<=0 ) nMerge = pDb->nMerge;
  5236         -  return doLsmWork(pDb, nMerge, nPage, pnWrite);
         5315  +
         5316  +  /* Convert from KB to pages */
         5317  +  nPgsz = lsmFsPageSize(pDb->pFS);
         5318  +  if( nKB>=0 ){
         5319  +    nPage = ((i64)nKB * 1024 + nPgsz - 1) / nPgsz;
         5320  +  }else{
         5321  +    nPage = -1;
         5322  +  }
         5323  +
         5324  +  rc = doLsmWork(pDb, nMerge, nPage, &nWrite);
         5325  +  
         5326  +  if( pnWrite ){
         5327  +    /* Convert back from pages to KB */
         5328  +    *pnWrite = (int)(((i64)nWrite * 1024 + nPgsz - 1) / nPgsz);
         5329  +  }
         5330  +  return rc;
  5237   5331   }
  5238   5332   
  5239   5333   int lsm_flush(lsm_db *db){
  5240   5334     int rc;
  5241   5335   
  5242   5336     if( db->nTransOpen>0 || db->pCsr ){
  5243   5337       rc = LSM_MISUSE_BKPT;
................................................................................
  5297   5391       int nRemaining;               /* Units of work to do before returning */
  5298   5392   
  5299   5393       nRemaining = nUnit * nDepth;
  5300   5394   #ifdef LSM_LOG_WORK
  5301   5395       lsmLogMessage(pDb, rc, "lsmSortedAutoWork(): %d*%d = %d pages", 
  5302   5396           nUnit, nDepth, nRemaining);
  5303   5397   #endif
         5398  +    assert( nRemaining>=0 );
  5304   5399       rc = doLsmWork(pDb, pDb->nMerge, nRemaining, 0);
  5305   5400       if( rc==LSM_BUSY ) rc = LSM_OK;
  5306   5401   
  5307   5402       if( bRestore && pDb->pCsr ){
         5403  +      lsmMCursorFreeCache(pDb);
  5308   5404         lsmFreeSnapshot(pDb->pEnv, pDb->pClient);
  5309   5405         pDb->pClient = 0;
  5310   5406         rc = lsmCheckpointLoad(pDb, 0);
  5311   5407         if( rc==LSM_OK ){
  5312   5408           rc = lsmCheckpointDeserialize(pDb, 0, pDb->aSnapshot, &pDb->pClient);
  5313   5409         }
  5314   5410         if( rc==LSM_OK ){

Changes to src/lsm_tree.c.

   263    263   ** discarded.
   264    264   */
   265    265   static void intArrayTruncate(IntArray *p, int nVal){
   266    266     p->nArray = nVal;
   267    267   }
   268    268   /* End of IntArray methods.
   269    269   ***********************************************************************/
          270  +
          271  +static int treeKeycmp(void *p1, int n1, void *p2, int n2){
          272  +  int res;
          273  +  res = memcmp(p1, p2, LSM_MIN(n1, n2));
          274  +  if( res==0 ) res = (n1-n2);
          275  +  return res;
          276  +}
   270    277   
   271    278   /*
   272    279   ** The pointer passed as the first argument points to an interior node,
   273    280   ** not a leaf. This function returns the offset of the iCell'th child
   274    281   ** sub-tree of the node.
   275    282   */
   276    283   static u32 getChildPtr(TreeNode *p, int iVersion, int iCell){
................................................................................
   283    290   ** Given an offset within the *-shm file, return the associated chunk number.
   284    291   */
   285    292   static int treeOffsetToChunk(u32 iOff){
   286    293     assert( LSM_SHM_CHUNK_SIZE==(1<<15) );
   287    294     return (int)(iOff>>15);
   288    295   }
   289    296   
          297  +#define treeShmptrUnsafe(pDb, iPtr) \
          298  +(&((u8*)((pDb)->apShm[(iPtr)>>15]))[(iPtr) & (LSM_SHM_CHUNK_SIZE-1)])
          299  +
   290    300   /*
   291    301   ** Return a pointer to the mapped memory location associated with *-shm 
   292    302   ** file offset iPtr.
   293    303   */
   294    304   static void *treeShmptr(lsm_db *pDb, u32 iPtr){
   295    305   
   296    306     assert( (iPtr>>15)<pDb->nShm );
   297    307     assert( pDb->apShm[iPtr>>15] );
   298    308   
   299         -  return iPtr?(&((u8*)(pDb->apShm[iPtr>>15]))[iPtr & (LSM_SHM_CHUNK_SIZE-1)]):0;
          309  +  return iPtr ? treeShmptrUnsafe(pDb, iPtr) : 0;
   300    310   }
   301    311   
   302    312   static ShmChunk * treeShmChunk(lsm_db *pDb, int iChunk){
   303    313     return (ShmChunk *)(pDb->apShm[iChunk]);
   304    314   }
   305    315   
   306    316   static ShmChunk * treeShmChunkRc(lsm_db *pDb, int iChunk, int *pRc){
................................................................................
   561    571   }
   562    572   
   563    573   /*
   564    574   ** Return a pointer to the mapping of the TreeKey object that the cursor
   565    575   ** is pointing to. 
   566    576   */
   567    577   static TreeKey *csrGetKey(TreeCursor *pCsr, TreeBlob *pBlob, int *pRc){
   568         -  TreeKey *pRet = (TreeKey *)treeShmkey(pCsr->pDb,
   569         -      pCsr->apTreeNode[pCsr->iNode]->aiKeyPtr[pCsr->aiCell[pCsr->iNode]], 
   570         -      TKV_LOADVAL, pBlob, pRc
   571         -  );
   572         -  assert( pRet==0 || assertFlagsOk(pRet->flags) );
          578  +  TreeKey *pRet;
          579  +  lsm_db *pDb = pCsr->pDb;
          580  +  u32 iPtr = pCsr->apTreeNode[pCsr->iNode]->aiKeyPtr[pCsr->aiCell[pCsr->iNode]];
          581  +
          582  +  assert( iPtr );
          583  +  pRet = treeShmptrUnsafe(pDb, iPtr);
          584  +  if( !(pRet->flags & LSM_CONTIGUOUS) ){
          585  +    pRet = treeShmkey(pDb, iPtr, TKV_LOADVAL, pBlob, pRc);
          586  +  }
          587  +
   573    588     return pRet;
   574    589   }
   575    590   
   576    591   /*
   577    592   ** Save the current position of tree cursor pCsr.
   578    593   */
   579    594   int lsmTreeCursorSave(TreeCursor *pCsr){
................................................................................
   717    732     u32 *piPtr, 
   718    733     void *pKey, int nKey,           /* Key data */
   719    734     void *pVal, int nVal,           /* Value data (or nVal<0 for delete) */
   720    735     int *pRc
   721    736   ){
   722    737     TreeKey *p;
   723    738     u32 iPtr;
          739  +  u32 iEnd;
   724    740     int nRem;
   725    741     u8 *a;
   726    742     int n;
   727    743   
   728    744     /* Allocate space for the TreeKey structure itself */
   729    745     *piPtr = iPtr = treeShmalloc(pDb, 1, sizeof(TreeKey), pRc);
   730    746     p = treeShmptr(pDb, iPtr);
................................................................................
   750    766         memcpy(aAlloc, &a[n-nRem], nAlloc);
   751    767         nRem -= nAlloc;
   752    768       }
   753    769       a = pVal;
   754    770       n = nRem = nVal;
   755    771       pVal = 0;
   756    772     }
          773  +
          774  +  iEnd = iPtr + sizeof(TreeKey) + nKey + LSM_MAX(0, nVal);
          775  +  if( (iPtr & ~(LSM_SHM_CHUNK_SIZE-1))!=(iEnd & ~(LSM_SHM_CHUNK_SIZE-1)) ){
          776  +    p->flags = 0;
          777  +  }else{
          778  +    p->flags = LSM_CONTIGUOUS;
          779  +  }
   757    780   
   758    781     if( *pRc ) return 0;
   759    782   #if 0
   760    783     printf("store: %d %s\n", (int)iPtr, (char *)pKey);
   761    784   #endif
   762    785     return p;
   763    786   }
................................................................................
  1043   1066       }
  1044   1067     }
  1045   1068   
  1046   1069     return rc;
  1047   1070   }
  1048   1071   
  1049   1072   void lsmTreeMakeOld(lsm_db *pDb){
         1073  +
         1074  +  /* A write transaction must be open. Otherwise the code below that
         1075  +  ** assumes (pDb->pClient->iLogOff) is current may malfunction. 
         1076  +  **
         1077  +  ** Update: currently this assert fails due to lsm_flush(), which does
         1078  +  ** not set nTransOpen.
         1079  +  */
         1080  +  assert( /* pDb->nTransOpen>0 && */ pDb->iReader>=0 );
         1081  +
  1050   1082     if( pDb->treehdr.iOldShmid==0 ){
  1051         -    pDb->treehdr.iOldLog = pDb->treehdr.log.aRegion[2].iEnd;
         1083  +    pDb->treehdr.iOldLog = (pDb->treehdr.log.aRegion[2].iEnd << 1);
         1084  +    pDb->treehdr.iOldLog |= (~(pDb->pClient->iLogOff) & (i64)0x0001);
         1085  +
  1052   1086       pDb->treehdr.oldcksum0 = pDb->treehdr.log.cksum0;
  1053   1087       pDb->treehdr.oldcksum1 = pDb->treehdr.log.cksum1;
  1054   1088       pDb->treehdr.iOldShmid = pDb->treehdr.iNextShmid-1;
  1055   1089       memcpy(&pDb->treehdr.oldroot, &pDb->treehdr.root, sizeof(TreeRoot));
  1056   1090   
  1057   1091       pDb->treehdr.root.iTransId = 1;
  1058   1092       pDb->treehdr.root.iRoot = 0;
................................................................................
  1079   1113   ** is initialized here - it will be copied into shared memory if log file
  1080   1114   ** recovery is successful.
  1081   1115   */
  1082   1116   int lsmTreeInit(lsm_db *pDb){
  1083   1117     ShmChunk *pOne;
  1084   1118     int rc = LSM_OK;
  1085   1119   
         1120  +  memset(&pDb->treehdr, 0, sizeof(TreeHeader));
  1086   1121     pDb->treehdr.root.iTransId = 1;
  1087   1122     pDb->treehdr.iFirst = 1;
  1088   1123     pDb->treehdr.nChunk = 2;
  1089   1124     pDb->treehdr.iWrite = LSM_SHM_CHUNK_SIZE + LSM_SHM_CHUNK_HDR;
  1090   1125     pDb->treehdr.iNextShmid = 2;
  1091   1126     pDb->treehdr.iUsedShmid = 1;
  1092   1127   
................................................................................
  1424   1459     int res;                        /* Result of seek operation on csr */
  1425   1460   
  1426   1461     assert( nVal>=0 || pVal==0 );
  1427   1462     assert_tree_looks_ok(LSM_OK, pTree);
  1428   1463     assert( flags==LSM_INSERT       || flags==LSM_POINT_DELETE 
  1429   1464          || flags==LSM_START_DELETE || flags==LSM_END_DELETE 
  1430   1465     );
         1466  +  assert( (flags & LSM_CONTIGUOUS)==0 );
  1431   1467   #if 0
  1432   1468     dump_tree_contents(pDb, "before");
  1433   1469   #endif
  1434   1470   
  1435   1471     if( p->iRoot ){
  1436   1472       TreeKey *pRes;                /* Key at end of seek operation */
  1437   1473       treeCursorInit(pDb, 0, &csr);
................................................................................
  1481   1517     }else{
  1482   1518       memset(&csr, 0, sizeof(TreeCursor));
  1483   1519     }
  1484   1520   
  1485   1521     /* Allocate and populate a new key-value pair structure */
  1486   1522     pTreeKey = newTreeKey(pDb, &iTreeKey, pKey, nKey, pVal, nVal, &rc);
  1487   1523     if( rc!=LSM_OK ) return rc;
  1488         -  pTreeKey->flags = flags;
         1524  +  assert( pTreeKey->flags==0 || pTreeKey->flags==LSM_CONTIGUOUS );
         1525  +  pTreeKey->flags |= flags;
  1489   1526   
  1490   1527     if( p->iRoot==0 ){
  1491   1528       /* The tree is completely empty. Add a new root node and install
  1492   1529       ** (pKey/nKey) as the middle entry. Even though it is a leaf at the
  1493   1530       ** moment, use newTreeNode() to allocate the node (i.e. allocate enough
  1494   1531       ** space for the fields used by interior nodes). This is because the
  1495   1532       ** treeInsert() routine may convert this node to an interior node. */
................................................................................
  1767   1804   ){
  1768   1805     int rc = LSM_OK;
  1769   1806     int bDone = 0;
  1770   1807     TreeRoot *p = &db->treehdr.root;
  1771   1808     TreeBlob blob = {0, 0};
  1772   1809   
  1773   1810     /* The range must be sensible - that (key1 < key2). */
  1774         -  assert( db->xCmp(pKey1, nKey1, pKey2, nKey2)<0 );
         1811  +  assert( treeKeycmp(pKey1, nKey1, pKey2, nKey2)<0 );
  1775   1812     assert( assert_delete_ranges_match(db) );
  1776   1813   
  1777   1814   #if 0
  1778   1815     static int nCall = 0;
  1779   1816     printf("\n");
  1780   1817     nCall++;
  1781   1818     printf("%d delete %s .. %s\n", nCall, (char *)pKey1, (char *)pKey2);
................................................................................
  1799   1836   
  1800   1837       /* If there is no such entry, or if it is greater than pKey2, then the
  1801   1838       ** tree now contains no keys in the range being deleted. In this case
  1802   1839       ** break out of the loop.  */
  1803   1840       bDone = 1;
  1804   1841       if( lsmTreeCursorValid(&csr) ){
  1805   1842         lsmTreeCursorKey(&csr, 0, &pDel, &nDel);
  1806         -      if( db->xCmp(pDel, nDel, pKey2, nKey2)<0 ) bDone = 0;
         1843  +      if( treeKeycmp(pDel, nDel, pKey2, nKey2)<0 ) bDone = 0;
  1807   1844       }
  1808   1845   
  1809   1846       if( bDone==0 ){
  1810   1847         if( csr.iNode==(p->nHeight-1) ){
  1811   1848           /* The element to delete already lies on a leaf node */
  1812   1849           rc = treeDeleteEntry(db, &csr, 0);
  1813   1850         }else{
................................................................................
  1916   1953   static int treeCsrCompare(TreeCursor *pCsr, void *pKey, int nKey){
  1917   1954     TreeKey *p;
  1918   1955     int cmp = 0;
  1919   1956     int rc = LSM_OK;
  1920   1957     assert( pCsr->iNode>=0 );
  1921   1958     p = csrGetKey(pCsr, &pCsr->blob, &rc);
  1922   1959     if( p ){
  1923         -    cmp = pCsr->pDb->xCmp(TKV_KEY(p), p->nKey, pKey, nKey);
         1960  +    cmp = treeKeycmp(TKV_KEY(p), p->nKey, pKey, nKey);
  1924   1961     }
  1925   1962     return cmp;
  1926   1963   }
  1927   1964   #endif
  1928   1965   
  1929   1966   
  1930   1967   /*
................................................................................
  1941   1978   **
  1942   1979   **   * If the tree is empty, leave the cursor at EOF and set *pRes to -1.
  1943   1980   */
  1944   1981   int lsmTreeCursorSeek(TreeCursor *pCsr, void *pKey, int nKey, int *pRes){
  1945   1982     int rc = LSM_OK;                /* Return code */
  1946   1983     lsm_db *pDb = pCsr->pDb;
  1947   1984     TreeRoot *pRoot = pCsr->pRoot;
  1948         -  int (*xCmp)(void *, int, void *, int) = pDb->xCmp;
  1949         -
  1950   1985     u32 iNodePtr;                   /* Location of current node in search */
  1951   1986   
  1952   1987     /* Discard any saved position data */
  1953   1988     treeCursorRestore(pCsr, 0);
  1954   1989   
  1955   1990     iNodePtr = pRoot->iRoot;
  1956   1991     if( iNodePtr==0 ){
................................................................................
  1961   1996     }else{
  1962   1997       TreeBlob b = {0, 0};
  1963   1998       int res = 0;                  /* Result of comparison function */
  1964   1999       int iNode = -1;
  1965   2000       while( iNodePtr ){
  1966   2001         TreeNode *pNode;            /* Node at location iNodePtr */
  1967   2002         int iTest;                  /* Index of second key to test (0 or 2) */
         2003  +      u32 iTreeKey;
  1968   2004         TreeKey *pTreeKey;          /* Key to compare against */
  1969   2005   
  1970         -      pNode = (TreeNode *)treeShmptr(pDb, iNodePtr);
         2006  +      pNode = (TreeNode *)treeShmptrUnsafe(pDb, iNodePtr);
  1971   2007         iNode++;
  1972   2008         pCsr->apTreeNode[iNode] = pNode;
  1973   2009   
  1974   2010         /* Compare (pKey/nKey) with the key in the middle slot of B-tree node
  1975   2011         ** pNode. The middle slot is never empty. If the comparison is a match,
  1976   2012         ** then the search is finished. Break out of the loop. */
  1977         -      pTreeKey = treeShmkey(pDb, pNode->aiKeyPtr[1], TKV_LOADKEY, &b, &rc);
  1978         -      if( rc!=LSM_OK ) break;
  1979         -      res = xCmp((void *)&pTreeKey[1], pTreeKey->nKey, pKey, nKey);
         2013  +      pTreeKey = treeShmptrUnsafe(pDb, pNode->aiKeyPtr[1]);
         2014  +      if( !(pTreeKey->flags & LSM_CONTIGUOUS) ){
         2015  +        pTreeKey = treeShmkey(pDb, pNode->aiKeyPtr[1], TKV_LOADKEY, &b, &rc);
         2016  +        if( rc!=LSM_OK ) break;
         2017  +      }
         2018  +      res = treeKeycmp((void *)&pTreeKey[1], pTreeKey->nKey, pKey, nKey);
  1980   2019         if( res==0 ){
  1981   2020           pCsr->aiCell[iNode] = 1;
  1982   2021           break;
  1983   2022         }
  1984   2023   
  1985   2024         /* Based on the results of the previous comparison, compare (pKey/nKey)
  1986   2025         ** to either the left or right key of the B-tree node, if such a key
  1987   2026         ** exists. */
  1988   2027         iTest = (res>0 ? 0 : 2);
  1989         -      pTreeKey = treeShmkey(pDb, pNode->aiKeyPtr[iTest], TKV_LOADKEY, &b, &rc);
  1990         -      if( rc ) break;
  1991         -      if( pTreeKey==0 ){
  1992         -        iTest = 1;
  1993         -      }else{
  1994         -        res = xCmp((void *)&pTreeKey[1], pTreeKey->nKey, pKey, nKey);
         2028  +      iTreeKey = pNode->aiKeyPtr[iTest];
         2029  +      if( iTreeKey ){
         2030  +        pTreeKey = treeShmptrUnsafe(pDb, iTreeKey);
         2031  +        if( !(pTreeKey->flags & LSM_CONTIGUOUS) ){
         2032  +          pTreeKey = treeShmkey(pDb, iTreeKey, TKV_LOADKEY, &b, &rc);
         2033  +          if( rc ) break;
         2034  +        }
         2035  +        res = treeKeycmp((void *)&pTreeKey[1], pTreeKey->nKey, pKey, nKey);
  1995   2036           if( res==0 ){
  1996   2037             pCsr->aiCell[iNode] = iTest;
  1997   2038             break;
  1998   2039           }
         2040  +      }else{
         2041  +        iTest = 1;
  1999   2042         }
  2000   2043   
  2001   2044         if( iNode<(pRoot->nHeight-1) ){
  2002   2045           iNodePtr = getChildPtr(pNode, pRoot->iTransId, iTest + (res<0));
  2003   2046         }else{
  2004   2047           iNodePtr = 0;
  2005   2048         }
................................................................................
  2076   2119         if( iCell<3 && pCsr->apTreeNode[pCsr->iNode]->aiKeyPtr[iCell] ) break;
  2077   2120       }
  2078   2121     }
  2079   2122   
  2080   2123   #ifndef NDEBUG
  2081   2124     if( pCsr->iNode>=0 ){
  2082   2125       TreeKey *pK2 = csrGetKey(pCsr, &pCsr->blob, &rc);
  2083         -    assert( rc || pDb->xCmp(TKV_KEY(pK2),pK2->nKey,TKV_KEY(pK1),pK1->nKey)>=0 );
         2126  +    assert( rc||treeKeycmp(TKV_KEY(pK2),pK2->nKey,TKV_KEY(pK1),pK1->nKey)>=0 );
  2084   2127     }
  2085   2128     tblobFree(pDb, &key1);
  2086   2129   #endif
  2087   2130   
  2088   2131     return rc;
  2089   2132   }
  2090   2133   
................................................................................
  2144   2187       }while( (--pCsr->iNode)>=0 );
  2145   2188       pCsr->aiCell[pCsr->iNode] = iCell;
  2146   2189     }
  2147   2190   
  2148   2191   #ifndef NDEBUG
  2149   2192     if( pCsr->iNode>=0 ){
  2150   2193       TreeKey *pK2 = csrGetKey(pCsr, &pCsr->blob, &rc);
  2151         -    assert( rc || pDb->xCmp(TKV_KEY(pK2), pK2->nKey, TKV_KEY(pK1), pK1->nKey)<0 );
         2194  +    assert( rc || treeKeycmp(TKV_KEY(pK2),pK2->nKey,TKV_KEY(pK1),pK1->nKey)<0 );
  2152   2195     }
  2153   2196     tblobFree(pDb, &key1);
  2154   2197   #endif
  2155   2198   
  2156   2199     return rc;
  2157   2200   }
  2158   2201   
................................................................................
  2198   2241     return rc;
  2199   2242   }
  2200   2243   
  2201   2244   int lsmTreeCursorFlags(TreeCursor *pCsr){
  2202   2245     int flags = 0;
  2203   2246     if( pCsr && pCsr->iNode>=0 ){
  2204   2247       int rc = LSM_OK;
  2205         -    TreeKey *pKey = (TreeKey *)treeShmptr(pCsr->pDb,
         2248  +    TreeKey *pKey = (TreeKey *)treeShmptrUnsafe(pCsr->pDb,
  2206   2249           pCsr->apTreeNode[pCsr->iNode]->aiKeyPtr[pCsr->aiCell[pCsr->iNode]]
  2207   2250       );
  2208   2251       assert( rc==LSM_OK );
  2209         -    flags = pKey->flags;
         2252  +    flags = (pKey->flags & ~LSM_CONTIGUOUS);
  2210   2253     }
  2211   2254     return flags;
  2212   2255   }
  2213   2256   
  2214   2257   int lsmTreeCursorKey(TreeCursor *pCsr, int *pFlags, void **ppKey, int *pnKey){
  2215   2258     TreeKey *pTreeKey;
  2216   2259     int rc = LSM_OK;
................................................................................
  2353   2396       if( treeHeaderChecksumOk(&pDb->treehdr) ){
  2354   2397         if( piRead ) *piRead = 2;
  2355   2398         return LSM_OK;
  2356   2399       }
  2357   2400   
  2358   2401       lsmShmBarrier(pDb);
  2359   2402     }
  2360         -  return LSM_PROTOCOL;
         2403  +  return LSM_PROTOCOL_BKPT;
  2361   2404   }
  2362   2405   
  2363   2406   int lsmTreeLoadHeaderOk(lsm_db *pDb, int iRead){
  2364   2407     TreeHeader *p = (iRead==1) ? &pDb->pShmhdr->hdr1 : &pDb->pShmhdr->hdr2;
  2365   2408     assert( iRead==1 || iRead==2 );
  2366   2409     return (0==memcmp(pDb->treehdr.aCksum, p->aCksum, sizeof(u32)*2));
  2367   2410   }

Changes to src/lsm_unix.c.

    34     34   
    35     35   #include <unistd.h>
    36     36   #include <errno.h>
    37     37   
    38     38   #include <sys/mman.h>
    39     39   #include "lsmInt.h"
    40     40   
           41  +/* There is no fdatasync() call on Android */
           42  +#ifdef __ANDROID__
           43  +# define fdatasync(x) fsync(x)
           44  +#endif
           45  +
    41     46   /*
    42     47   ** An open file is an instance of the following object
    43     48   */
    44     49   typedef struct PosixFile PosixFile;
    45     50   struct PosixFile {
    46     51     lsm_env *pEnv;                  /* The run-time environment */
    47     52     const char *zName;              /* Full path to file */
................................................................................
    49     54     int shmfd;                      /* Shared memory file-descriptor */
    50     55     void *pMap;                     /* Pointer to mapping of file fd */
    51     56     off_t nMap;                     /* Size of mapping at pMap in bytes */
    52     57     int nShm;                       /* Number of entries in array apShm[] */
    53     58     void **apShm;                   /* Array of 32K shared memory segments */
    54     59   };
    55     60   
    56         -static int lsm_ioerr(void){ return LSM_IOERR; }
    57         -
    58     61   static char *posixShmFile(PosixFile *p){
    59     62     char *zShm;
    60     63     int nName = strlen(p->zName);
    61     64     zShm = (char *)lsmMalloc(p->pEnv, nName+4+1);
    62     65     if( zShm ){
    63     66       memcpy(zShm, p->zName, nName);
    64     67       memcpy(&zShm[nName], "-shm", 5);
    65     68     }
    66     69     return zShm;
    67     70   }
    68     71   
    69     72   static int lsmPosixOsOpen(
    70     73     lsm_env *pEnv,
    71         -  const char *zFile, 
           74  +  const char *zFile,
           75  +  int flags,
    72     76     lsm_file **ppFile
    73     77   ){
    74     78     int rc = LSM_OK;
    75     79     PosixFile *p;
    76     80   
    77     81     p = lsm_malloc(pEnv, sizeof(PosixFile));
    78     82     if( p==0 ){
    79     83       rc = LSM_NOMEM;
    80     84     }else{
           85  +    int bReadonly = (flags & LSM_OPEN_READONLY);
           86  +    int oflags = (bReadonly ? O_RDONLY : (O_RDWR|O_CREAT));
    81     87       memset(p, 0, sizeof(PosixFile));
    82     88       p->zName = zFile;
    83     89       p->pEnv = pEnv;
    84         -    p->fd = open(zFile, O_RDWR|O_CREAT, 0644);
           90  +    p->fd = open(zFile, oflags, 0644);
    85     91       if( p->fd<0 ){
    86     92         lsm_free(pEnv, p);
    87     93         p = 0;
    88         -      rc = lsm_ioerr();
           94  +      if( errno==ENOENT ){
           95  +        rc = lsmErrorBkpt(LSM_IOERR_NOENT);
           96  +      }else{
           97  +        rc = LSM_IOERR_BKPT;
           98  +      }
    89     99       }
    90    100     }
    91    101   
    92    102     *ppFile = (lsm_file *)p;
    93    103     return rc;
    94    104   }
    95    105   
................................................................................
   101    111   ){
   102    112     int rc = LSM_OK;
   103    113     PosixFile *p = (PosixFile *)pFile;
   104    114     off_t offset;
   105    115   
   106    116     offset = lseek(p->fd, (off_t)iOff, SEEK_SET);
   107    117     if( offset!=iOff ){
   108         -    rc = lsm_ioerr();
          118  +    rc = LSM_IOERR_BKPT;
   109    119     }else{
   110    120       ssize_t prc = write(p->fd, pData, (size_t)nData);
   111         -    if( prc<0 ) rc = lsm_ioerr();
          121  +    if( prc<0 ) rc = LSM_IOERR_BKPT;
   112    122     }
   113    123   
   114    124     return rc;
   115    125   }
   116    126   
   117    127   static int lsmPosixOsTruncate(
   118    128     lsm_file *pFile,                /* File to write to */
   119    129     lsm_i64 nSize                   /* Size to truncate file to */
   120    130   ){
   121         -  int rc = LSM_OK;
          131  +  PosixFile *p = (PosixFile *)pFile;
          132  +  int rc = LSM_OK;                /* Return code */
   122    133     int prc;                        /* Posix Return Code */
   123         -  PosixFile *p = (PosixFile *)pFile;
   124         -
   125         -  prc = ftruncate(p->fd, (off_t)nSize);
   126         -  if( prc<0 ) rc = lsm_ioerr();
          134  +  struct stat sStat;              /* Result of fstat() invocation */
          135  +  
          136  +  prc = fstat(p->fd, &sStat);
          137  +  if( prc==0 && sStat.st_size>nSize ){
          138  +    prc = ftruncate(p->fd, (off_t)nSize);
          139  +  }
          140  +  if( prc<0 ) rc = LSM_IOERR_BKPT;
   127    141   
   128    142     return rc;
   129    143   }
   130    144   
   131    145   static int lsmPosixOsRead(
   132    146     lsm_file *pFile,                /* File to read from */
   133    147     lsm_i64 iOff,                   /* Offset to read from */
................................................................................
   136    150   ){
   137    151     int rc = LSM_OK;
   138    152     PosixFile *p = (PosixFile *)pFile;
   139    153     off_t offset;
   140    154   
   141    155     offset = lseek(p->fd, (off_t)iOff, SEEK_SET);
   142    156     if( offset!=iOff ){
   143         -    rc = lsm_ioerr();
          157  +    rc = LSM_IOERR_BKPT;
   144    158     }else{
   145    159       ssize_t prc = read(p->fd, pData, (size_t)nData);
   146    160       if( prc<0 ){ 
   147         -      rc = lsm_ioerr();
          161  +      rc = LSM_IOERR_BKPT;
   148    162       }else if( prc<nData ){
   149    163         memset(&((u8 *)pData)[prc], 0, nData - prc);
   150    164       }
   151    165   
   152    166     }
   153    167   
   154    168     return rc;
................................................................................
   161    175     PosixFile *p = (PosixFile *)pFile;
   162    176     int prc = 0;
   163    177   
   164    178     if( p->pMap ){
   165    179       prc = msync(p->pMap, p->nMap, MS_SYNC);
   166    180     }
   167    181     if( prc==0 ) prc = fdatasync(p->fd);
   168         -  if( prc<0 ) rc = lsm_ioerr();
          182  +  if( prc<0 ) rc = LSM_IOERR_BKPT;
   169    183   #else
   170    184     (void)pFile;
   171    185   #endif
   172    186   
   173    187     return rc;
   174    188   }
   175    189   
................................................................................
   237    251   
   238    252     if( p->pMap ){
   239    253       munmap(p->pMap, p->nMap);
   240    254       *ppOut = p->pMap = 0;
   241    255       *pnOut = p->nMap = 0;
   242    256     }
   243    257   
   244         -  memset(&buf, 0, sizeof(buf));
   245         -  prc = fstat(p->fd, &buf);
   246         -  if( prc!=0 ) return LSM_IOERR_BKPT;
   247         -  iSz = buf.st_size;
   248         -  if( iSz<iMin ){
   249         -    iSz = ((iMin + (2<<20) - 1) / (2<<20)) * (2<<20);
   250         -    prc = ftruncate(p->fd, iSz);
          258  +  if( iMin>=0 ){
          259  +    memset(&buf, 0, sizeof(buf));
          260  +    prc = fstat(p->fd, &buf);
   251    261       if( prc!=0 ) return LSM_IOERR_BKPT;
          262  +    iSz = buf.st_size;
          263  +    if( iSz<iMin ){
          264  +      iSz = ((iMin + (2<<20) - 1) / (2<<20)) * (2<<20);
          265  +      prc = ftruncate(p->fd, iSz);
          266  +      if( prc!=0 ) return LSM_IOERR_BKPT;
          267  +    }
          268  +
          269  +    p->pMap = mmap(0, iSz, PROT_READ|PROT_WRITE, MAP_SHARED, p->fd, 0);
          270  +    p->nMap = iSz;
   252    271     }
   253    272   
   254         -  p->pMap = mmap(0, iSz, PROT_READ|PROT_WRITE, MAP_SHARED, p->fd, 0);
   255         -  p->nMap = iSz;
   256         -
   257    273     *ppOut = p->pMap;
   258    274     *pnOut = p->nMap;
   259    275     return LSM_OK;
   260    276   }
   261    277   
   262    278   static int lsmPosixOsFullpath(
   263    279     lsm_env *pEnv,
................................................................................
   338    354     static const short aType[3] = { F_UNLCK, F_RDLCK, F_WRLCK };
   339    355     struct flock lock;
   340    356   
   341    357     assert( aType[LSM_LOCK_UNLOCK]==F_UNLCK );
   342    358     assert( aType[LSM_LOCK_SHARED]==F_RDLCK );
   343    359     assert( aType[LSM_LOCK_EXCL]==F_WRLCK );
   344    360     assert( eType>=0 && eType<array_size(aType) );
   345         -  assert( iLock>0 && iLock<=16 );
          361  +  assert( iLock>0 && iLock<=32 );
   346    362   
   347    363     memset(&lock, 0, sizeof(lock));
   348    364     lock.l_whence = SEEK_SET;
   349    365     lock.l_len = 1;
   350    366     lock.l_type = aType[eType];
   351    367     lock.l_start = (4096-iLock);
   352    368   
   353    369     if( fcntl(p->fd, F_SETLK, &lock) ){
   354    370       int e = errno;
   355    371       if( e==EACCES || e==EAGAIN ){
   356    372         rc = LSM_BUSY;
   357    373       }else{
   358         -      rc = LSM_IOERR;
          374  +      rc = LSM_IOERR_BKPT;
   359    375       }
   360    376     }
          377  +
          378  +  return rc;
          379  +}
          380  +
          381  +int lsmPosixOsTestLock(lsm_file *pFile, int iLock, int nLock, int eType){
          382  +  int rc = LSM_OK;
          383  +  PosixFile *p = (PosixFile *)pFile;
          384  +  static const short aType[3] = { 0, F_RDLCK, F_WRLCK };
          385  +  struct flock lock;
          386  +
          387  +  assert( eType==LSM_LOCK_SHARED || eType==LSM_LOCK_EXCL );
          388  +  assert( aType[LSM_LOCK_SHARED]==F_RDLCK );
          389  +  assert( aType[LSM_LOCK_EXCL]==F_WRLCK );
          390  +  assert( eType>=0 && eType<array_size(aType) );
          391  +  assert( iLock>0 && iLock<=32 );
          392  +
          393  +  memset(&lock, 0, sizeof(lock));
          394  +  lock.l_whence = SEEK_SET;
          395  +  lock.l_len = nLock;
          396  +  lock.l_type = aType[eType];
          397  +  lock.l_start = (4096-iLock);
          398  +
          399  +  if( fcntl(p->fd, F_GETLK, &lock) ){
          400  +    rc = LSM_IOERR_BKPT;
          401  +  }else if( lock.l_type!=F_UNLCK ){
          402  +    rc = LSM_BUSY;
          403  +  }
   361    404   
   362    405     return rc;
   363    406   }
   364    407   
   365    408   int lsmPosixOsShmMap(lsm_file *pFile, int iChunk, int sz, void **ppShm){
   366    409     PosixFile *p = (PosixFile *)pFile;
   367    410   
................................................................................
   405    448       p->nShm = nNew;
   406    449     }
   407    450   
   408    451     if( p->apShm[iChunk]==0 ){
   409    452       p->apShm[iChunk] = mmap(0, LSM_SHM_CHUNK_SIZE, 
   410    453           PROT_READ|PROT_WRITE, MAP_SHARED, p->shmfd, iChunk*LSM_SHM_CHUNK_SIZE
   411    454       );
   412         -    if( p->apShm[iChunk]==0 ) return LSM_IOERR;
          455  +    if( p->apShm[iChunk]==0 ) return LSM_IOERR_BKPT;
   413    456     }
   414    457   
   415    458     *ppShm = p->apShm[iChunk];
   416    459     return LSM_OK;
   417    460   }
   418    461   
   419    462   void lsmPosixOsShmBarrier(void){
................................................................................
   448    491      close(p->fd);
   449    492      lsm_free(p->pEnv, p->apShm);
   450    493      lsm_free(p->pEnv, p);
   451    494      return LSM_OK;
   452    495   }
   453    496   
   454    497   static int lsmPosixOsSleep(lsm_env *pEnv, int us){
   455         -  if( usleep(us) ){
   456         -    return LSM_IOERR;
   457         -  }
          498  +#if 0
          499  +  /* Apparently on Android usleep() returns void */
          500  +  if( usleep(us) ) return LSM_IOERR;
          501  +#endif
          502  +  usleep(us);
   458    503     return LSM_OK;
   459    504   }
   460    505   
   461    506   /****************************************************************************
   462    507   ** Memory allocation routines.
   463    508   */
   464    509   #define BLOCK_HDR_SIZE ROUND8( sizeof(sqlite4_size_t) )
................................................................................
   711    756   #endif
   712    757       lsmPosixOsMap,           /* xMap */
   713    758       lsmPosixOsUnmap,         /* xUnmap */
   714    759       lsmPosixOsFileid,        /* xFileid */
   715    760       lsmPosixOsClose,         /* xClose */
   716    761       lsmPosixOsUnlink,        /* xUnlink */
   717    762       lsmPosixOsLock,          /* xLock */
          763  +    lsmPosixOsTestLock,      /* xTestLock */
   718    764       lsmPosixOsShmMap,        /* xShmMap */
   719    765       lsmPosixOsShmBarrier,    /* xShmBarrier */
   720    766       lsmPosixOsShmUnmap,      /* xShmUnmap */
   721    767       /***** memory allocation *********/
   722    768       0,                       /* pMemCtx */
   723    769       lsmPosixOsMalloc,        /* xMalloc */
   724    770       lsmPosixOsRealloc,       /* xRealloc */

Changes to src/main.c.

    25     25   #ifdef SQLITE4_ENABLE_ICU
    26     26   # include "sqliteicu.h"
    27     27   #endif
    28     28   
    29     29   /*
    30     30   ** Dummy function used as a unique symbol for SQLITE4_DYNAMIC
    31     31   */
    32         -void sqlite4_dynamic(void *p){ (void)p; }
    33         -
    34         -#ifndef SQLITE4_AMALGAMATION
    35         -/* IMPLEMENTATION-OF: R-46656-45156 The sqlite4_version[] string constant
    36         -** contains the text of SQLITE4_VERSION macro. 
    37         -*/
    38         -const char sqlite4_version[] = SQLITE4_VERSION;
    39         -#endif
           32  +void sqlite4_dynamic(void *pArg,void *p){ (void)pArg; (void)p; }
    40     33   
    41     34   /* IMPLEMENTATION-OF: R-53536-42575 The sqlite4_libversion() function returns
    42     35   ** a pointer to the to the sqlite4_version[] string constant. 
    43     36   */
    44     37   const char *sqlite4_libversion(void){ return SQLITE4_VERSION; }
    45     38   
    46     39   /* IMPLEMENTATION-OF: R-63124-39300 The sqlite4_sourceid() function returns a
................................................................................
    67     60   ** SQLITE4_ENABLE_IOTRACE is enabled, then messages describing
    68     61   ** I/O active are written using this function.  These messages
    69     62   ** are intended for debugging activity only.
    70     63   */
    71     64   void (*sqlite4IoTrace)(const char*, ...) = 0;
    72     65   #endif
    73     66   
    74         -/*
    75         -** Initialize SQLite.  
    76         -**
    77         -** This routine must be called to initialize the run-time environment
    78         -** As long as you do not compile with SQLITE4_OMIT_AUTOINIT
    79         -** this routine will be called automatically by key routines such as
    80         -** sqlite4_open().  
    81         -**
    82         -** This routine is a no-op except on its very first call for a given
    83         -** sqlite4_env object, or for the first call after a call to sqlite4_shutdown.
    84         -**
    85         -** This routine is not threadsafe.  It should be called from a single
    86         -** thread to initialized the library in a multi-threaded system.  Other
    87         -** threads should avoid using the sqlite4_env object until after it has
    88         -** completely initialized.
    89         -*/
    90         -int sqlite4_initialize(sqlite4_env *pEnv){
    91         -  MUTEX_LOGIC( sqlite4_mutex *pMaster; )       /* The main static mutex */
    92         -  int rc;                                      /* Result code */
    93         -
    94         -  if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;
    95         -
    96         -  /* If SQLite is already completely initialized, then this call
    97         -  ** to sqlite4_initialize() should be a no-op.  But the initialization
    98         -  ** must be complete.  So isInit must not be set until the very end
    99         -  ** of this routine.
   100         -  */
   101         -  if( pEnv->isInit ) return SQLITE4_OK;
   102         -
   103         -  /* Initialize the mutex subsystem
   104         -  */
   105         -  rc = sqlite4MutexInit(pEnv);
   106         -  if( rc ){
   107         -    sqlite4MallocEnd(pEnv);
   108         -    return rc;
   109         -  }
   110         -
   111         -  /* Initialize the memory allocation subsystem
   112         -  */
   113         -  rc = sqlite4MallocInit(pEnv);
   114         -  if( rc ) return rc;
   115         -
   116         -  /* Create required mutexes
   117         -  */
   118         -  if( pEnv->bCoreMutex ){
   119         -    pEnv->pMemMutex = sqlite4MutexAlloc(pEnv, SQLITE4_MUTEX_FAST);
   120         -    pEnv->pPrngMutex = sqlite4MutexAlloc(pEnv, SQLITE4_MUTEX_FAST);
   121         -    pEnv->pFactoryMutex = sqlite4MutexAlloc(pEnv, SQLITE4_MUTEX_FAST);
   122         -    if( pEnv->pMemMutex==0
   123         -     || pEnv->pPrngMutex==0
   124         -     || pEnv->pFactoryMutex==0
   125         -    ){
   126         -      rc = SQLITE4_NOMEM;
   127         -    }
   128         -  }else{
   129         -    pEnv->pMemMutex = 0;
   130         -    pEnv->pPrngMutex = 0;
   131         -  }
   132         -  pEnv->isInit = 1;
   133         -
   134         -  sqlite4OsInit(pEnv);
   135         -
   136         -  /* Register global functions */
   137         -  if( rc==SQLITE4_OK ){
   138         -    sqlite4RegisterGlobalFunctions(pEnv);
   139         -  }
   140         -
   141         -  /* The following is just a sanity check to make sure SQLite has
   142         -  ** been compiled correctly.  It is important to run this code, but
   143         -  ** we don't want to run it too often and soak up CPU cycles for no
   144         -  ** reason.  So we run it once during initialization.
   145         -  */
   146         -#ifndef NDEBUG
   147         -#ifndef SQLITE4_OMIT_FLOATING_POINT
   148         -  /* This section of code's only "output" is via assert() statements. */
   149         -  if ( rc==SQLITE4_OK ){
   150         -    u64 x = (((u64)1)<<63)-1;
   151         -    double y;
   152         -    assert(sizeof(x)==8);
   153         -    assert(sizeof(x)==sizeof(y));
   154         -    memcpy(&y, &x, 8);
   155         -    assert( sqlite4IsNaN(y) );
   156         -  }
   157         -#endif
   158         -#endif
   159         -
   160         -  return rc;
   161         -}
   162         -
   163         -/*
   164         -** Undo the effects of sqlite4_initialize().  Must not be called while
   165         -** there are outstanding database connections or memory allocations or
   166         -** while any part of SQLite is otherwise in use in any thread.  This
   167         -** routine is not threadsafe.  But it is safe to invoke this routine
   168         -** on when SQLite is already shut down.  If SQLite is already shut down
   169         -** when this routine is invoked, then this routine is a harmless no-op.
   170         -*/
   171         -int sqlite4_shutdown(sqlite4_env *pEnv){
   172         -  if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;
   173         -  if( pEnv->isInit ){
   174         -    KVFactory *pMkr;
   175         -    sqlite4_mutex_free(pEnv->pFactoryMutex);
   176         -    sqlite4_mutex_free(pEnv->pPrngMutex);
   177         -    sqlite4_mutex_free(pEnv->pMemMutex);
   178         -    pEnv->pMemMutex = 0;
   179         -    while( (pMkr = pEnv->pFactory)!=0 && pMkr->isPerm==0 ){
   180         -      KVFactory *pNext = pMkr->pNext;
   181         -      sqlite4_free(pEnv, pMkr);
   182         -      pMkr = pNext;
   183         -    }
   184         -    sqlite4MutexEnd(pEnv);
   185         -    sqlite4MallocEnd(pEnv);
   186         -    pEnv->isInit = 0;
   187         -  }
   188         -  return SQLITE4_OK;
   189         -}
   190         -
   191         -/*
   192         -** Return the size of an sqlite4_env object
   193         -*/
   194         -int sqlite4_env_size(void){ return sizeof(sqlite4_env); }
   195         -
   196         -/*
   197         -** This API allows applications to modify the configuration described by
   198         -** an sqlite4_env object.
   199         -*/
   200         -int sqlite4_env_config(sqlite4_env *pEnv, int op, ...){
   201         -  va_list ap;
   202         -  int rc = SQLITE4_OK;
   203         -
   204         -  if( pEnv==0 ) pEnv = sqlite4_env_default();
   205         -
   206         -  va_start(ap, op);
   207         -  switch( op ){
   208         -    /*
   209         -    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_INIT, template);
   210         -    **
   211         -    ** Turn bulk memory into a new sqlite4_env object.  The template is
   212         -    ** a prior sqlite4_env that is used as a template in initializing the
   213         -    ** new sqlite4_env object.  The size of the bulk memory must be at
   214         -    ** least as many bytes as returned from sqlite4_env_size().
   215         -    */
   216         -    case SQLITE4_ENVCONFIG_INIT: {
   217         -      /* Disable all mutexing */
   218         -      sqlite4_env *pTemplate = va_arg(ap, sqlite4_env*);
   219         -      int n = pTemplate->nByte;
   220         -      if( n>sizeof(sqlite4_env) ) n = sizeof(sqlite4_env);
   221         -      memcpy(pEnv, pTemplate, n);
   222         -      pEnv->pFactory = &sqlite4BuiltinFactory;
   223         -      pEnv->isInit = 0;
   224         -      break;
   225         -    }
   226         -
   227         -    /* Mutex configuration options are only available in a threadsafe
   228         -    ** compile. 
   229         -    */
   230         -#if defined(SQLITE4_THREADSAFE) && SQLITE4_THREADSAFE>0
   231         -    /*
   232         -    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_SINGLETHREAD);
   233         -    **
   234         -    ** Configure this environment for a single-threaded application.
   235         -    */
   236         -    case SQLITE4_ENVCONFIG_SINGLETHREAD: {
   237         -      /* Disable all mutexing */
   238         -      if( pEnv->isInit ){ rc = SQLITE4_MISUSE; break; }
   239         -      pEnv->bCoreMutex = 0;
   240         -      pEnv->bFullMutex = 0;
   241         -      break;
   242         -    }
   243         -
   244         -    /*
   245         -    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_MULTITHREAD);
   246         -    **
   247         -    ** Configure this environment for a multi-threaded application where
   248         -    ** the same database connection is never used by more than a single
   249         -    ** thread at a time.
   250         -    */
   251         -    case SQLITE4_ENVCONFIG_MULTITHREAD: {
   252         -      /* Disable mutexing of database connections */
   253         -      /* Enable mutexing of core data structures */
   254         -      if( pEnv->isInit ){ rc = SQLITE4_MISUSE; break; }
   255         -      pEnv->bCoreMutex = 1;
   256         -      pEnv->bFullMutex = 0;
   257         -      break;
   258         -    }
   259         -
   260         -    /*
   261         -    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_MULTITHREAD);
   262         -    **
   263         -    ** Configure this environment for an unrestricted multi-threaded
   264         -    ** application where any thread can do whatever it wants with any
   265         -    ** database connection at any time.
   266         -    */
   267         -    case SQLITE4_ENVCONFIG_SERIALIZED: {
   268         -      /* Enable all mutexing */
   269         -      if( pEnv->isInit ){ rc = SQLITE4_MISUSE; break; }
   270         -      pEnv->bCoreMutex = 1;
   271         -      pEnv->bFullMutex = 1;
   272         -      break;
   273         -    }
   274         -
   275         -    /*
   276         -    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_MUTEXT, sqlite4_mutex_methods*)
   277         -    **
   278         -    ** Configure this environment to use the mutex routines specified by the
   279         -    ** argument.
   280         -    */
   281         -    case SQLITE4_ENVCONFIG_MUTEX: {
   282         -      /* Specify an alternative mutex implementation */
   283         -      if( pEnv->isInit ){ rc = SQLITE4_MISUSE; break; }
   284         -      pEnv->mutex = *va_arg(ap, sqlite4_mutex_methods*);
   285         -      break;
   286         -    }
   287         -
   288         -    /*
   289         -    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_GETMUTEX, sqlite4_mutex_methods*)
   290         -    **
   291         -    ** Copy the mutex routines in use by this environment into the structure
   292         -    ** given in the argument.
   293         -    */
   294         -    case SQLITE4_ENVCONFIG_GETMUTEX: {
   295         -      /* Retrieve the current mutex implementation */
   296         -      *va_arg(ap, sqlite4_mutex_methods*) = pEnv->mutex;
   297         -      break;
   298         -    }
   299         -#endif
   300         -
   301         -
   302         -    /*
   303         -    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_MALLOC, sqlite4_mem_methods*)
   304         -    **
   305         -    ** Set the memory allocation routines to be used by this environment.
   306         -    */
   307         -    case SQLITE4_ENVCONFIG_MALLOC: {
   308         -      /* Specify an alternative malloc implementation */
   309         -      if( pEnv->isInit ) return SQLITE4_MISUSE;
   310         -      pEnv->m = *va_arg(ap, sqlite4_mem_methods*);
   311         -      break;
   312         -    }
   313         -
   314         -    /*
   315         -    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_GETMALLOC, sqlite4_mem_methods*)
   316         -    **
   317         -    ** Copy the memory allocation routines in use by this environment
   318         -    ** into the structure given in the argument.
   319         -    */
   320         -    case SQLITE4_ENVCONFIG_GETMALLOC: {
   321         -      /* Retrieve the current malloc() implementation */
   322         -      if( pEnv->m.xMalloc==0 ) sqlite4MemSetDefault(pEnv);
   323         -      *va_arg(ap, sqlite4_mem_methods*) = pEnv->m;
   324         -      break;
   325         -    }
   326         -
   327         -    /* sqlite4_env_config(p, SQLITE4_ENVCONFIG_MEMSTAT, int onoff);
   328         -    **
   329         -    ** Enable or disable collection of memory usage statistics according to
   330         -    ** the onoff parameter.  
   331         -    */
   332         -    case SQLITE4_ENVCONFIG_MEMSTATUS: {
   333         -      /* Enable or disable the malloc status collection */
   334         -      pEnv->bMemstat = va_arg(ap, int);
   335         -      break;
   336         -    }
   337         -
   338         -    /*
   339         -    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_LOOKASIDE, size, count);
   340         -    **
   341         -    ** Set the default lookaside memory settings for all subsequent
   342         -    ** database connections constructed in this environment.  The size
   343         -    ** parameter is the size of each lookaside memory buffer and the
   344         -    ** count parameter is the number of lookaside buffers.  Set both
   345         -    ** to zero to disable lookaside memory.
   346         -    */
   347         -    case SQLITE4_ENVCONFIG_LOOKASIDE: {
   348         -      pEnv->szLookaside = va_arg(ap, int);
   349         -      pEnv->nLookaside = va_arg(ap, int);
   350         -      break;
   351         -    }
   352         -    
   353         -    /*
   354         -    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_LOG, xOutput, pArg);
   355         -    **
   356         -    ** Set the log function that is called in response to sqlite4_log()
   357         -    ** calls.
   358         -    */
   359         -    case SQLITE4_ENVCONFIG_LOG: {
   360         -      /* MSVC is picky about pulling func ptrs from va lists.
   361         -      ** http://support.microsoft.com/kb/47961
   362         -      ** pEnv->xLog = va_arg(ap, void(*)(void*,int,const char*));
   363         -      */
   364         -      typedef void(*LOGFUNC_t)(void*,int,const char*);
   365         -      pEnv->xLog = va_arg(ap, LOGFUNC_t);
   366         -      pEnv->pLogArg = va_arg(ap, void*);
   367         -      break;
   368         -    }
   369         -
   370         -    /*
   371         -    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_KVSTORE_PUSH, zName,xFactory);
   372         -    **
   373         -    ** Push a new KVStore factory onto the factory stack.  The new factory
   374         -    ** takes priority over prior factories.
   375         -    */
   376         -    case SQLITE4_ENVCONFIG_KVSTORE_PUSH: {
   377         -      const char *zName = va_arg(ap, const char*);
   378         -      int nName = sqlite4Strlen30(zName);
   379         -      KVFactory *pMkr = sqlite4_malloc(pEnv, sizeof(*pMkr)+nName+1);
   380         -      char *z;
   381         -      if( pMkr==0 ) return SQLITE4_NOMEM;
   382         -      z = (char*)&pMkr[1];
   383         -      memcpy(z, zName, nName+1);
   384         -      memset(pMkr, 0, sizeof(*pMkr));
   385         -      pMkr->zName = z;
   386         -      pMkr->xFactory = va_arg(ap, sqlite4_kvfactory);
   387         -      sqlite4_mutex_enter(pEnv->pFactoryMutex);
   388         -      pMkr->pNext = pEnv->pFactory;
   389         -      pEnv->pFactory = pMkr;
   390         -      sqlite4_mutex_leave(pEnv->pFactoryMutex);
   391         -      break;
   392         -    }
   393         -
   394         -    /*
   395         -    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_KVSTORE_POP, zName, &pxFact);
   396         -    **
   397         -    ** Remove a KVStore factory from the stack.
   398         -    */
   399         -    /*
   400         -    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_KVSTORE_GET, zName, &pxFact);
   401         -    **
   402         -    ** Get the current factory pointer with the given name but leave the
   403         -    ** factory on the stack.
   404         -    */
   405         -    case SQLITE4_ENVCONFIG_KVSTORE_POP:
   406         -    case SQLITE4_ENVCONFIG_KVSTORE_GET: {
   407         -      typedef int (**PxFact)(sqlite4_env*,KVStore**,const char*,unsigned);
   408         -      const char *zName = va_arg(ap, const char*);
   409         -      KVFactory *pMkr, **ppPrev;
   410         -      PxFact pxFact;
   411         -
   412         -      pxFact = va_arg(ap,PxFact);
   413         -      *pxFact = 0;
   414         -      sqlite4_mutex_enter(pEnv->pFactoryMutex);
   415         -      ppPrev = &pEnv->pFactory;
   416         -      pMkr = *ppPrev;
   417         -      while( pMkr && strcmp(zName, pMkr->zName)!=0 ){
   418         -        ppPrev = &pMkr->pNext;
   419         -        pMkr = *ppPrev;
   420         -      }
   421         -      if( pMkr ){
   422         -        *pxFact = pMkr->xFactory;
   423         -        if( op==SQLITE4_ENVCONFIG_KVSTORE_POP && pMkr->isPerm==0 ){
   424         -          *ppPrev = pMkr->pNext;
   425         -          sqlite4_free(pEnv, pMkr);
   426         -        }
   427         -      }
   428         -      sqlite4_mutex_leave(pEnv->pFactoryMutex);
   429         -      break;
   430         -    }
   431         -
   432         -
   433         -    default: {
   434         -      rc = SQLITE4_ERROR;
   435         -      break;
   436         -    }
   437         -  }
   438         -  va_end(ap);
   439         -  return rc;
   440         -}
   441         -
   442     67   /*
   443     68   ** Set up the lookaside buffers for a database connection.
   444     69   ** Return SQLITE4_OK on success.  
   445     70   ** If lookaside is already active, return SQLITE4_BUSY.
   446     71   **
   447     72   ** The sz parameter is the number of bytes in each lookaside slot.
   448     73   ** The cnt parameter is the number of slots.  If pStart is NULL the
................................................................................
   662    287       for(i=0; i<nIn; i++){
   663    288         aOut[i] = sqlite4_tolower(aIn[i]);
   664    289       }
   665    290     }
   666    291     return nIn;
   667    292   }
   668    293   
   669         -/*
   670         -** Return the ROWID of the most recent insert
   671         -*/
   672         -sqlite4_int64 sqlite4_last_insert_rowid(sqlite4 *db){
   673         -  return db->lastRowid;
   674         -}
   675         -
   676    294   /*
   677    295   ** Return the number of changes in the most recent call to sqlite4_exec().
   678    296   */
   679    297   int sqlite4_changes(sqlite4 *db){
   680    298     return db->nChange;
   681    299   }
   682    300   
................................................................................
  1263    881     sqlite4_mutex_enter(db->mutex);
  1264    882     if( db->mallocFailed ){
  1265    883       z = (void *)outOfMem;
  1266    884     }else{
  1267    885       z = sqlite4_value_text16(db->pErr);
  1268    886       if( z==0 ){
  1269    887         sqlite4ValueSetStr(db->pErr, -1, sqlite4ErrStr(db->errCode),
  1270         -           SQLITE4_UTF8, SQLITE4_STATIC);
          888  +           SQLITE4_UTF8, SQLITE4_STATIC, 0);
  1271    889         z = sqlite4_value_text16(db->pErr);
  1272    890       }
  1273    891       /* A malloc() may have failed within the call to sqlite4_value_text16()
  1274    892       ** above. If this is the case, then the db->mallocFailed flag needs to
  1275    893       ** be cleared before returning. Do this directly, instead of via
  1276    894       ** sqlite4ApiExit(), to avoid setting the database handle error message.
  1277    895       */
................................................................................
  1929   1547     db->xCollNeeded16 = xCollNeeded16;
  1930   1548     db->pCollNeededArg = pCollNeededArg;
  1931   1549     sqlite4_mutex_leave(db->mutex);
  1932   1550     return SQLITE4_OK;
  1933   1551   }
  1934   1552   #endif /* SQLITE4_OMIT_UTF16 */
  1935   1553   
  1936         -#ifndef SQLITE4_OMIT_DEPRECATED
  1937         -/*
  1938         -** This function is now an anachronism. It used to be used to recover from a
  1939         -** malloc() failure, but SQLite now does this automatically.
  1940         -*/
  1941         -int sqlite4_global_recover(void){
  1942         -  return SQLITE4_OK;
  1943         -}
  1944         -#endif
  1945         -
  1946   1554   /*
  1947   1555   ** Test to see whether or not the database connection is in autocommit
  1948   1556   ** mode.  Return TRUE if it is and FALSE if not.  Autocommit mode is on
  1949   1557   ** by default.  Autocommit is disabled by a BEGIN statement and reenabled
  1950   1558   ** by the next COMMIT or ROLLBACK.
  1951         -**
  1952         -******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
  1953   1559   */
  1954   1560   int sqlite4_get_autocommit(sqlite4 *db){
  1955   1561     return (db->pSavepoint==0);
  1956   1562   }
  1957   1563   
  1958   1564   /*
  1959   1565   ** The following routines are subtitutes for constants SQLITE4_CORRUPT,

Changes to src/math.c.

   211    211     r.sign = A.sign ^ B.sign;
   212    212     r.approx = A.approx | B.approx;
   213    213     if( r.approx==0 && A.m%B.m!=0 ) r.approx = 1;
   214    214     r.m = A.m/B.m;
   215    215     r.e = A.e - B.e;
   216    216     return r;
   217    217   }
          218  +
          219  +/*
          220  +** Test if A is infinite.
          221  +*/
          222  +int sqlite4_num_isinf(sqlite4_num A){
          223  +  return A.e>SQLITE4_MX_EXP && A.m!=0;
          224  +}
          225  +
          226  +/*
          227  +** Test if A is NaN.
          228  +*/
          229  +int sqlite4_num_isnan(sqlite4_num A){
          230  +  return A.e>SQLITE4_MX_EXP && A.m==0; 
          231  +}
   218    232   
   219    233   /*
   220    234   ** Compare numbers A and B.  Return:
   221    235   **
   222    236   **    1     if A<B
   223    237   **    2     if A==B
   224    238   **    3     if A>B
................................................................................
   237    251       return A.sign ? 1 : 3;
   238    252     }
   239    253     if( B.e>SQLITE4_MX_EXP ){
   240    254       if( B.m==0 ) return 0;
   241    255       return B.sign ? 3 : 1;
   242    256     }
   243    257     if( A.sign!=B.sign ){
          258  +    if ( A.m==0 && B.m==0 ) return 2;
   244    259       return A.sign ? 1 : 3;
   245    260     }
   246    261     adjustExponent(&A, &B);
   247    262     if( A.sign ){
   248    263       sqlite4_num t = A;
   249    264       A = B;
   250    265       B = t;
................................................................................
   319    334       i = incr;
   320    335     }else if( zIn[0]=='+' ){
   321    336       i = incr;
   322    337     }else{
   323    338       i = 0;
   324    339     }
   325    340     if( nIn<=0 ) goto not_a_valid_number;
   326         -  if( nIn>=incr*2
          341  +  if( nIn>=incr*3
   327    342      && ((c=zIn[i])=='i' || c=='I')
   328    343      && ((c=zIn[i+incr])=='n' || c=='N')
   329    344      && ((c=zIn[i+incr*2])=='f' || c=='F')
   330    345     ){
   331    346       r.e = SQLITE4_MX_EXP+1;
   332    347       r.m = nIn<=i+incr*3 || zIn[i+incr*3]==0;
   333    348       return r;
   334    349     }
   335    350     while( i<nIn && (c = zIn[i])!=0 ){
   336    351       i += incr;
   337    352       if( c>='0' && c<='9' ){
   338         -      if( c==0 && nDigit==0 ){
          353  +      if( c=='0' && nDigit==0 ){
   339    354           if( seenRadix && r.e > -(SQLITE4_MX_EXP+1000) ) r.e--;
   340    355           continue;
   341    356         }
   342    357         nDigit++;
   343    358         if( nDigit<=18 ){
   344    359           r.m = (r.m*10) + c - '0';
   345    360           if( seenRadix ) r.e--;
   346    361         }else{
   347    362           if( c!='0' ) r.approx = 1;
   348    363           if( !seenRadix ) r.e++;
   349    364         }
   350    365       }else if( c=='.' ){
   351    366         seenRadix = 1;
   352         -    }else{
          367  +    }else if( c=='e' || c=='E' ){
          368  +      int exp = 0;
          369  +      int expsign = 0;
          370  +      int nEDigit = 0;
          371  +      if( zIn[i]=='-' ){
          372  +        expsign = 1;
          373  +        i += incr;
          374  +      }else if( zIn[i]=='+' ){
          375  +        i += incr;
          376  +      }
          377  +      if( i>=nIn ) goto not_a_valid_number;
          378  +      while( i<nIn && (c = zIn[i])!=0 ){
          379  +        i += incr;
          380  +        if( c<'0' || c>'9' ) goto not_a_valid_number;
          381  +        if( c=='0' && nEDigit==0 ) continue;
          382  +        nEDigit++;
          383  +        if( nEDigit>3 ) goto not_a_valid_number;
          384  +        exp = exp*10 + c - '0';
          385  +      }
          386  +      if( expsign ) exp = -exp;
          387  +      r.e += exp;
   353    388         break;
          389  +    }else{
          390  +      goto not_a_valid_number;
   354    391       }
   355    392     }
   356         -  if( c=='e' || c=='E' ){
   357         -    int exp = 0;
   358         -    int expsign = 0;
   359         -    int nEDigit = 0;
   360         -    if( zIn[i]=='-' ){
   361         -      expsign = 1;
   362         -      i += incr;
   363         -    }else if( zIn[i]=='+' ){
   364         -      i += incr;
   365         -    }
   366         -    if( i>=nIn ) goto not_a_valid_number;
   367         -    while( i<nIn && (c = zIn[i])!=0  ){
   368         -      i += incr;
   369         -      if( c<'0' || c>'9' ) break;
   370         -      if( c=='0' && nEDigit==0 ) continue;
   371         -      nEDigit++;
   372         -      if( nEDigit>3 ) goto not_a_valid_number;
   373         -      exp = exp*10 + c - '0';
   374         -    }
   375         -    if( expsign ) exp = -exp;
   376         -    r.e += exp;
   377         -  }
   378         -  if( c!=0 ) goto not_a_valid_number;
   379    393     return r;
   380    394     
   381    395   not_a_valid_number:
   382    396     r.e = SQLITE4_MX_EXP+1;
   383    397     r.m = 0;
   384    398     return r;  
   385    399   }
          400  +
          401  +/*
          402  +** Convert an sqlite4_int64 to a number and return that number.
          403  +*/
          404  +sqlite4_num sqlite4_num_from_int64(sqlite4_int64 n){
          405  +  sqlite4_num r;
          406  +  r.approx = 0;
          407  +  r.e = 0;
          408  +  r.sign = n < 0;
          409  +  if( n>=0 ){
          410  +    r.m = n;
          411  +  }else if( n!=SMALLEST_INT64 ){
          412  +    r.m = -n;
          413  +  }else{
          414  +    r.m = 1+(u64)LARGEST_INT64;
          415  +  }
          416  +  return r;
          417  +}
   386    418   
   387    419   /*
   388    420   ** Convert an integer into text in the buffer supplied. The
   389    421   ** text is zero-terminated and right-justified in the buffer.
   390    422   ** A pointer to the first character of text is returned.
   391    423   **
   392    424   ** The buffer needs to be at least 21 bytes in length.
................................................................................
   465    497       zNum += m;
   466    498       n -= m;
   467    499       removeTrailingZeros(zNum, &n);
   468    500       if( n>0 ){
   469    501         zOut[0] = '.';
   470    502         memcpy(zOut+1, zNum, n);
   471    503         nOut += n;
          504  +      zOut[n+1] = 0;
          505  +    }else{
          506  +      zOut[0] = 0;
   472    507       }
   473         -    zOut[n+1] = 0;
   474    508       return nOut;
   475    509     }
   476    510     if( x.e<0 && x.e >= -n-5 ){
   477    511       /* Values less than 1 and with no more than 5 subsequent zeros prior
   478    512       ** to the first significant digit.  Ex:  0.0000012345 */
   479    513       int j = -(n + x.e);
   480    514       memcpy(zOut, "0.", 2);

Changes to src/mem.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   **
    13     13   ** This file contains the implementation of the "sqlite4_mm" memory
    14     14   ** allocator object.
    15     15   */
    16         -#include "sqlite4.h"
    17         -#include "mem.h"
    18         -#include <stdlib.h>
           16  +#include "sqliteInt.h"
    19     17   
    20     18   /*************************************************************************
    21     19   ** The SQLITE4_MM_SYSTEM memory allocator.  This allocator uses the
    22     20   ** malloc/realloc/free from the system library.  It also tries to use
    23     21   ** the memory allocation sizer from the system library if such a routine
    24     22   ** exists.  If there is no msize in the system library, then each allocation
    25     23   ** is increased in size by 8 bytes and the size of the allocation is stored
................................................................................
    96     94   #endif
    97     95   
    98     96   #endif /* __APPLE__ or not __APPLE__ */
    99     97   
   100     98   /*
   101     99   ** Implementations of core routines
   102    100   */
   103         -static void *mmSysMalloc(sqlite4_mm *pMM, sqlite4_int64 iSize){
          101  +static void *mmSysMalloc(sqlite4_mm *pMM, sqlite4_size_t iSize){
   104    102   #ifdef SQLITE4_MALLOCSIZE
   105    103     return SQLITE4_MALLOC(iSize);
   106    104   #else
   107    105     unsigned char *pRes = SQLITE4_MALLOC(iSize+8);
   108    106     if( pRes ){
   109         -    *(sqlite4_int64*)pRes = iSize;
          107  +    *(sqlite4_size_t*)pRes = iSize;
   110    108       pRes += 8;
   111    109     }
   112    110     return pRes;
   113    111   #endif
   114    112   }
   115         -static void *mmSysRealloc(sqlite4_mm *pMM, void *pOld, sqlite4_int64 iSz){
          113  +static void *mmSysRealloc(sqlite4_mm *pMM, void *pOld, sqlite4_size_t iSz){
   116    114   #ifdef SQLITE4_MALLOCSIZE
   117    115     return SQLITE4_REALLOC(pOld, iSz);
   118    116   #else
   119    117     unsigned char *pRes;
   120    118     if( pOld==0 ) return mmSysMalloc(pMM, iSz);
   121    119     pRes = (unsigned char*)pOld;
   122    120     pRes -= 8;
   123    121     pRes = SQLITE4_REALLOC(pRes, iSz+8);
   124    122     if( pRes ){
   125         -    *(sqlite4_int64*)pRes = iSz;
          123  +    *(sqlite4_size_t*)pRes = iSz;
   126    124       pRes += 8;
   127    125     }
   128    126     return pRes;
   129    127   #endif 
   130    128   }
   131    129   static void mmSysFree(sqlite4_mm *pNotUsed, void *pOld){
   132    130   #ifdef SQLITE4_MALLOCSIZE
................................................................................
   135    133     unsigned char *pRes;
   136    134     if( pOld==0 ) return;
   137    135     pRes = (unsigned char *)pOld;
   138    136     pRes -= 8;
   139    137     SQLITE4_FREE(pRes);
   140    138   #endif
   141    139   }
   142         -static sqlite4_int64 mmSysMsize(sqlite4_mm *pNotUsed, void *pOld){
          140  +static sqlite4_size_t mmSysMsize(sqlite4_mm *pNotUsed, void *pOld){
   143    141   #ifdef SQLITE4_MALLOCSIZE
   144    142     return SQLITE4_MALLOCSIZE(pOld);
   145    143   #else
   146    144     unsigned char *pX;
   147    145     if( pOld==0 ) return 0;
   148    146     pX = (unsigned char *)pOld;
   149    147     pX -= 8;
   150         -  return *(sqlite4_int64*)pX;
          148  +  return *(sqlite4_size_t*)pX;
   151    149   #endif
   152    150   }
   153    151   
   154    152   static const sqlite4_mm_methods mmSysMethods = {
   155    153     /* iVersion */    1,
   156    154     /* xMalloc  */    mmSysMalloc,
   157    155     /* xRealloc */    mmSysRealloc,
   158    156     /* xFree    */    mmSysFree,
   159    157     /* xMsize   */    mmSysMsize,
   160    158     /* xMember  */    0,
   161    159     /* xBenign  */    0,
          160  +  /* xStat    */    0,
          161  +  /* xCtrl    */    0,
   162    162     /* xFinal   */    0
   163    163   };
   164         -static sqlite4_mm mmSystem =  {
          164  +sqlite4_mm sqlite4MMSystem =  {
   165    165     /* pMethods */    &mmSysMethods
   166    166   };
   167    167   
          168  +/* The system memory allocator is the default. */
          169  +sqlite4_mm *sqlite4_mm_default(void){ return &sqlite4MMSystem; }
          170  +
   168    171   /*************************************************************************
   169    172   ** The SQLITE4_MM_OVERFLOW memory allocator.
   170    173   **
   171    174   ** This memory allocator has two child memory allocators, A and B.  Always
   172    175   ** try to fulfill the request using A first, then overflow to B if the request
   173    176   ** on A fails.  The A allocator must support the xMember method.
   174    177   */
................................................................................
   175    178   struct mmOvfl {
   176    179     sqlite4_mm base;    /* Base class - must be first */
   177    180     int (*xMemberOfA)(sqlite4_mm*, const void*);
   178    181     sqlite4_mm *pA;     /* Primary memory allocator */
   179    182     sqlite4_mm *pB;     /* Backup memory allocator in case pA fails */
   180    183   };
   181    184   
   182         -static void *mmOvflMalloc(sqlite4_mm *pMM, sqlite4_int64 iSz){
          185  +static void *mmOvflMalloc(sqlite4_mm *pMM, sqlite4_size_t iSz){
   183    186     const struct mmOvfl *pOvfl = (const struct mmOvfl*)pMM;
   184    187     void *pRes;
   185    188     pRes = pOvfl->pA->pMethods->xMalloc(pOvfl->pA, iSz);
   186    189     if( pRes==0 ){
   187    190       pRes = pOvfl->pB->pMethods->xMalloc(pOvfl->pB, iSz);
   188    191     }
   189    192     return pRes;
   190    193   }
   191         -static void *mmOvflRealloc(sqlite4_mm *pMM, void *pOld, sqlite4_int64 iSz){
          194  +static void *mmOvflRealloc(sqlite4_mm *pMM, void *pOld, sqlite4_size_t iSz){
   192    195     const struct mmOvfl *pOvfl;
   193         -  void *pRes;
          196  +  void *pRes, *pAlt;
   194    197     if( pOld==0 ) return mmOvflMalloc(pMM, iSz);
   195    198     pOvfl = (const struct mmOvfl*)pMM;
   196    199     if( pOvfl->xMemberOfA(pOvfl->pA, pOld) ){
   197    200       pRes = pOvfl->pA->pMethods->xRealloc(pOvfl->pA, pOld, iSz);
          201  +    if( pRes==0 && (pAlt = pOvfl->pB->pMethods->xMalloc(pOvfl->pB, iSz))!=0 ){
          202  +      sqlite4_size_t nOld = pOvfl->pA->pMethods->xMsize(pOvfl->pA, pOld);
          203  +      assert( nOld<iSz );
          204  +      memcpy(pAlt, pOld, (size_t)nOld);
          205  +      pOvfl->pA->pMethods->xFree(pOvfl->pA, pOld);
          206  +      pRes = pAlt;
          207  +    }
   198    208     }else{
   199    209       pRes = pOvfl->pB->pMethods->xRealloc(pOvfl->pB, pOld, iSz);
   200    210     }
   201    211     return pRes;
   202    212   }
   203    213   static void mmOvflFree(sqlite4_mm *pMM, void *pOld){
   204    214     const struct mmOvfl *pOvfl;
................................................................................
   206    216     pOvfl = (const struct mmOvfl*)pMM;
   207    217     if( pOvfl->xMemberOfA(pOvfl->pA, pOld) ){
   208    218       pOvfl->pA->pMethods->xFree(pOvfl->pA, pOld);
   209    219     }else{
   210    220       pOvfl->pB->pMethods->xFree(pOvfl->pB, pOld);
   211    221     }
   212    222   }
   213         -static sqlite4_int64 mmOvflMsize(sqlite4_mm *pMM, void *pOld){
          223  +static sqlite4_size_t mmOvflMsize(sqlite4_mm *pMM, void *pOld){
   214    224     const struct mmOvfl *pOvfl;
   215         -  sqlite4_int64 iSz;
          225  +  sqlite4_size_t iSz;
   216    226     if( pOld==0 ) return 0;
   217    227     pOvfl = (const struct mmOvfl*)pMM;
   218    228     if( pOvfl->xMemberOfA(pOvfl->pA, pOld) ){
   219    229       iSz = sqlite4_mm_msize(pOvfl->pA, pOld);
   220    230     }else{
   221    231       iSz = sqlite4_mm_msize(pOvfl->pB, pOld);
   222    232     }
................................................................................
   251    261     /* iVersion */    1,
   252    262     /* xMalloc  */    mmOvflMalloc,
   253    263     /* xRealloc */    mmOvflRealloc,
   254    264     /* xFree    */    mmOvflFree,
   255    265     /* xMsize   */    mmOvflMsize,
   256    266     /* xMember  */    mmOvflMember,
   257    267     /* xBenign  */    mmOvflBenign,
          268  +  /* xStat    */    0,
          269  +  /* xCtrl    */    0,
   258    270     /* xFinal   */    mmOvflFinal
   259    271   };
   260    272   static sqlite4_mm *mmOvflNew(sqlite4_mm *pA, sqlite4_mm *pB){
   261    273     struct mmOvfl *pOvfl;
   262    274     if( pA->pMethods->xMember==0 ) return 0;
   263    275     pOvfl = sqlite4_mm_malloc(pA, sizeof(*pOvfl));
   264    276     if( pOvfl==0 ){
................................................................................
   286    298   */
   287    299   struct mmOnesz {
   288    300     sqlite4_mm base;            /* Base class.  Must be first. */
   289    301     const void *pSpace;         /* Space to allocate */
   290    302     const void *pLast;          /* Last possible allocation */
   291    303     struct mmOneszBlock *pFree; /* List of free blocks */
   292    304     int sz;                     /* Size of each allocation */
          305  +  unsigned nFailSize;         /* Failures due to size */
          306  +  unsigned nFailMem;          /* Failures due to OOM */
          307  +  unsigned nSlot;             /* Number of available slots */
          308  +  unsigned nUsed;             /* Current number of slots in use */
          309  +  unsigned nUsedHw;           /* Highwater mark for slots in use */
          310  +  sqlite4_size_t mxSize;      /* Maximum request size */
   293    311   };
   294    312   
   295    313   /* A free block in the buffer */
   296    314   struct mmOneszBlock {
   297    315     struct mmOneszBlock *pNext;  /* Next on the freelist */
   298    316   };
   299    317   
   300         -static void *mmOneszMalloc(sqlite4_mm *pMM, sqlite4_int64 iSz){
          318  +static void *mmOneszMalloc(sqlite4_mm *pMM, sqlite4_size_t iSz){
   301    319     struct mmOnesz *pOnesz = (struct mmOnesz*)pMM;
   302    320     void *pRes;
   303         -  if( iSz>pOnesz->sz ) return 0;
   304         -  if( pOnesz->pFree==0 ) return 0;
          321  +  if( iSz>pOnesz->mxSize ) pOnesz->mxSize = iSz;
          322  +  if( iSz>pOnesz->sz ){ pOnesz->nFailSize++; return 0; }
          323  +  if( pOnesz->pFree==0 ){ pOnesz->nFailMem++;  return 0; }
          324  +  pOnesz->nUsed++;
          325  +  if( pOnesz->nUsed>pOnesz->nUsedHw ) pOnesz->nUsedHw = pOnesz->nUsed;
   305    326     pRes = pOnesz->pFree;
   306    327     pOnesz->pFree = pOnesz->pFree->pNext;
   307    328     return pRes;
   308    329   }
   309    330   static void mmOneszFree(sqlite4_mm *pMM, void *pOld){
   310    331     struct mmOnesz *pOnesz = (struct mmOnesz*)pMM;
   311    332     if( pOld ){
   312    333       struct mmOneszBlock *pBlock = (struct mmOneszBlock*)pOld;
   313    334       pBlock->pNext = pOnesz->pFree;
   314    335       pOnesz->pFree = pBlock;
          336  +    pOnesz->nUsed--;
   315    337     }
   316    338   }
   317         -static void *mmOneszRealloc(sqlite4_mm *pMM, void *pOld, sqlite4_int64 iSz){
          339  +static void *mmOneszRealloc(sqlite4_mm *pMM, void *pOld, sqlite4_size_t iSz){
   318    340     struct mmOnesz *pOnesz = (struct mmOnesz*)pMM;
   319    341     if( pOld==0 ) return mmOneszMalloc(pMM, iSz);
   320    342     if( iSz<=0 ){
   321    343       mmOneszFree(pMM, pOld);
   322    344       return 0;
   323    345     }
   324    346     if( iSz>pOnesz->sz ) return 0;
   325    347     return pOld;
   326    348   }
   327         -static sqlite4_int64 mmOneszMsize(sqlite4_mm *pMM, void *pOld){
          349  +static sqlite4_size_t mmOneszMsize(sqlite4_mm *pMM, void *pOld){
   328    350     struct mmOnesz *pOnesz = (struct mmOnesz*)pMM;
   329    351     return pOld ? pOnesz->sz : 0;  
   330    352   }
   331    353   static int mmOneszMember(sqlite4_mm *pMM, const void *pOld){
   332    354     struct mmOnesz *pOnesz = (struct mmOnesz*)pMM;
   333    355     return pOld && pOld>=pOnesz->pSpace && pOld<=pOnesz->pLast;
          356  +}
          357  +static sqlite4_int64 mmOneszStat(sqlite4_mm *pMM, int eType, unsigned flgs){
          358  +  struct mmOnesz *pOnesz = (struct mmOnesz*)pMM;
          359  +  sqlite4_int64 x = -1;
          360  +  switch( eType ){
          361  +    case SQLITE4_MMSTAT_OUT: {
          362  +      x = pOnesz->nUsed*pOnesz->sz;
          363  +      break;
          364  +    }
          365  +    case SQLITE4_MMSTAT_OUT_HW: {
          366  +      x = pOnesz->nUsedHw*pOnesz->sz;
          367  +      if( flgs & SQLITE4_MMSTAT_RESET ) pOnesz->nUsedHw = pOnesz->nUsed;
          368  +      break;
          369  +    }
          370  +    case SQLITE4_MMSTAT_UNITS: {
          371  +      x = pOnesz->nUsed;
          372  +      break;
          373  +    }
          374  +    case SQLITE4_MMSTAT_UNITS_HW: {
          375  +      x = pOnesz->nUsedHw;
          376  +      if( flgs & SQLITE4_MMSTAT_RESET ) pOnesz->nUsedHw = pOnesz->nUsed;
          377  +      break;
          378  +    }
          379  +    case SQLITE4_MMSTAT_SIZE: {
          380  +      x = pOnesz->mxSize;
          381  +      if( flgs & SQLITE4_MMSTAT_RESET ) pOnesz->mxSize = 0;
          382  +      break;
          383  +    }
          384  +    case SQLITE4_MMSTAT_SZFAULT: {
          385  +      x = pOnesz->nFailSize;
          386  +      if( flgs & SQLITE4_MMSTAT_RESET ) pOnesz->nFailSize = 0;
          387  +      break;
          388  +    }
          389  +    case SQLITE4_MMSTAT_MEMFAULT: {
          390  +      x = pOnesz->nFailMem;
          391  +      if( flgs & SQLITE4_MMSTAT_RESET ) pOnesz->nFailMem = 0;
          392  +      break;
          393  +    }
          394  +    case SQLITE4_MMSTAT_FAULT: {
          395  +      x = pOnesz->nFailSize + pOnesz->nFailMem;
          396  +      if( flgs & SQLITE4_MMSTAT_RESET ){
          397  +        pOnesz->nFailSize = 0;
          398  +        pOnesz->nFailMem = 0;
          399  +      }
          400  +      break;
          401  +    }
          402  +  }
          403  +  return x;
   334    404   }
   335    405   static const sqlite4_mm_methods mmOneszMethods = {
   336    406     /* iVersion */    1,
   337    407     /* xMalloc  */    mmOneszMalloc,
   338    408     /* xRealloc */    mmOneszRealloc,
   339    409     /* xFree    */    mmOneszFree,
   340    410     /* xMsize   */    mmOneszMsize,
   341    411     /* xMember  */    mmOneszMember,
   342    412     /* xBenign  */    0,
          413  +  /* xStat    */    mmOneszStat,
          414  +  /* xCtrl    */    0,
   343    415     /* xFinal   */    0
   344    416   };
   345    417   static sqlite4_mm *mmOneszNew(void *pSpace, int sz, int cnt){
   346    418     struct mmOnesz *pOnesz;
   347    419     unsigned char *pMem;
   348         -  if( sz<sizeof(*pOnesz) ) return 0;
   349         -  if( cnt<2 ) return 0;
          420  +  int n;
          421  +  if( sz<sizeof(struct mmOneszBlock) ) return 0;
   350    422     pMem = (unsigned char*)pSpace;
   351    423     pOnesz = (struct mmOnesz*)pMem;
   352         -  pMem += sz;
          424  +  n = (sizeof(*pOnesz) + sz - 1)/sz;
          425  +  pMem += sz*n;
          426  +  cnt -= n;
          427  +  if( cnt<2 ) return 0;
          428  +  memset(pOnesz, 0, sizeof(*pOnesz));
   353    429     pOnesz->base.pMethods = &mmOneszMethods;
   354    430     pOnesz->pSpace = (const void*)pMem;
   355    431     pOnesz->sz = sz;
   356    432     pOnesz->pLast = (const void*)(pMem + sz*(cnt-2));
   357    433     pOnesz->pFree = 0;
   358    434     while( cnt ){
   359    435       struct mmOneszBlock *pBlock = (struct mmOneszBlock*)pMem;
................................................................................
   364    440     }
   365    441     return &pOnesz->base;
   366    442   }
   367    443   
   368    444   /*************************************************************************
   369    445   ** Main interfaces.
   370    446   */
   371         -void *sqlite4_mm_malloc(sqlite4_mm *pMM, sqlite4_int64 iSize){
   372         -  if( pMM==0 ) pMM = &mmSystem;
          447  +void *sqlite4_mm_malloc(sqlite4_mm *pMM, sqlite4_size_t iSize){
          448  +  if( pMM==0 ) pMM = &sqlite4MMSystem;
   373    449     return pMM->pMethods->xMalloc(pMM,iSize);
   374    450   }
   375         -void *sqlite4_mm_realloc(sqlite4_mm *pMM, void *pOld, sqlite4_int64 iSize){
   376         -  if( pMM==0 ) pMM = &mmSystem;
          451  +void *sqlite4_mm_realloc(sqlite4_mm *pMM, void *pOld, sqlite4_size_t iSize){
          452  +  if( pMM==0 ) pMM = &sqlite4MMSystem;
   377    453     return pMM->pMethods->xRealloc(pMM,pOld,iSize);
   378    454   }
   379    455   void sqlite4_mm_free(sqlite4_mm *pMM, void *pOld){
   380         -  if( pMM==0 ) pMM = &mmSystem;
          456  +  if( pMM==0 ) pMM = &sqlite4MMSystem;
   381    457     pMM->pMethods->xFree(pMM,pOld);
   382    458   }
   383         -sqlite4_int64 sqlite4_mm_msize(sqlite4_mm *pMM, void *pOld){
   384         -  if( pMM==0 ) pMM = &mmSystem;
          459  +sqlite4_size_t sqlite4_mm_msize(sqlite4_mm *pMM, void *pOld){
          460  +  if( pMM==0 ) pMM = &sqlite4MMSystem;
   385    461     return pMM->pMethods->xMsize(pMM,pOld);
   386    462   }
   387    463   int sqlite4_mm_member(sqlite4_mm *pMM, const void *pOld){
   388    464     return (pMM && pMM->pMethods->xMember!=0) ?
   389    465               pMM->pMethods->xMember(pMM,pOld) : -1;
   390    466   }
   391         -void sqlite4_mm_benign_failure(sqlite4_mm *pMM, int bEnable){
          467  +void sqlite4_mm_benign_failures(sqlite4_mm *pMM, int bEnable){
   392    468     if( pMM && pMM->pMethods->xBenign ){
   393    469       pMM->pMethods->xBenign(pMM, bEnable);
   394    470     }
          471  +}
          472  +sqlite4_int64 sqlite4_mm_stat(sqlite4_mm *pMM, int eStatType, unsigned flags){
          473  +  if( pMM==0 ) return -1;
          474  +  if( pMM->pMethods->xStat==0 ) return -1;
          475  +  return pMM->pMethods->xStat(pMM, eStatType, flags);
          476  +}
          477  +int sqlite4_mm_control(sqlite4_mm *pMM, int eCtrlType, ...){
          478  +  int rc = SQLITE4_NOTFOUND;
          479  +  if( pMM && pMM->pMethods->xCtrl ){
          480  +    va_list ap;
          481  +    va_start(ap, eCtrlType);
          482  +    rc = pMM->pMethods->xCtrl(pMM, eCtrlType, ap);
          483  +    va_end(ap);
          484  +  }
          485  +  return rc;
   395    486   }
   396    487   void sqlite4_mm_destroy(sqlite4_mm *pMM){
   397    488     if( pMM && pMM->pMethods->xFinal ) pMM->pMethods->xFinal(pMM);
   398    489   }
   399    490   
   400    491   /*
   401    492   ** Create a new memory allocation object.  eType determines the type of
................................................................................
   404    495   sqlite4_mm *sqlite4_mm_new(sqlite4_mm_type eType, ...){
   405    496     va_list ap;
   406    497     sqlite4_mm *pMM;
   407    498   
   408    499     va_start(ap, eType);
   409    500     switch( eType ){
   410    501       case SQLITE4_MM_SYSTEM: {
   411         -      pMM = &mmSystem;
          502  +      pMM = &sqlite4MMSystem;
   412    503         break;
   413    504       }
   414    505       case SQLITE4_MM_OVERFLOW: {
   415    506         sqlite4_mm *pA = va_arg(ap, sqlite4_mm*);
   416    507         sqlite4_mm *pB = va_arg(ap, sqlite4_mm*);
   417    508         pMM = mmOvflNew(pA, pB);
   418    509         break;

Changes to src/mem.h.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** This header file defines the interface that the SQLite4 memory
    13         -** management logic.
    14     12   **
    15         -** Some of this will eventually fold into sqliteInt.h.
           13  +** This file defines the sqlite4_mm "SQLite4 Memory Manager" object and
           14  +** its interfaces.
    16     15   */
    17     16   
    18     17   
    19     18   /*
    20     19   ** object declarations
    21     20   */
    22     21   typedef struct sqlite4_mm sqlite4_mm;
................................................................................
    28     27   ** applications can supply their on customized memory allocators.
    29     28   */
    30     29   struct sqlite4_mm {
    31     30     const sqlite4_mm_methods *pMethods;
    32     31   };
    33     32   
    34     33   /*
    35         -** An instance of the following object defines a BESPOKE memory alloator
           34  +** Memory statistics reporting
           35  +*/
           36  +typedef enum {
           37  +  SQLITE4_MMSTAT_OUT = 1,         /* Bytes of memory outstanding */
           38  +  SQLITE4_MMSTAT_UNITS = 2,       /* Separate allocations outstanding */
           39  +  SQLITE4_MMSTAT_SIZE = 3,        /* Size of the allocation */
           40  +  SQLITE4_MMSTAT_SZFAULT = 4,     /* Number of faults due to size */
           41  +  SQLITE4_MMSTAT_MEMFAULT = 5,    /* Number of faults due to out of space */
           42  +  SQLITE4_MMSTAT_FAULT = 6,       /* Total number of faults */
           43  +};
           44  +
           45  +/*
           46  +** Bit flags for the 3rd parameter of xStat()
           47  +*/
           48  +#define SQLITE4_MMSTAT_HIGHWATER  0x01
           49  +#define SQLITE4_MMSTAT_RESET      0x02
           50  +#define SQLITE4_MMSTAT_HWRESET    0x03
           51  +
           52  +/*
           53  +** An instance of the following object defines the methods on
           54  +** a BESPOKE memory allocator.
    36     55   */
    37     56   struct sqlite4_mm_methods {
    38     57     int iVersion;
    39     58     void *(*xMalloc)(sqlite4_mm*, sqlite4_int64);
    40     59     void *(*xRealloc)(sqlite4_mm*, void*, sqlite4_int64);
    41     60     void (*xFree)(sqlite4_mm*, void*);
    42     61     sqlite4_int64 (*xMsize)(sqlite4_mm*, void*);
    43     62     int (*xMember)(sqlite4_mm*, const void*);
    44     63     void (*xBenign)(sqlite4_mm*, int);
           64  +  sqlite4_int64 (*xStat)(sqlite4_mm*, sqlite4_mm_stattype, unsigned flags);
    45     65     void (*xFinal)(sqlite4_mm*);
    46     66   };
    47     67   
    48     68   /*
    49     69   ** Available memory management types:
    50     70   */
    51     71   typedef enum {
    52         -  SQLITE4_MM_SYSTEM,         /* Use the system malloc() */
    53         -  SQLITE4_MM_ONESIZE,        /* All allocations map to a fixed size */
    54         -  SQLITE4_MM_OVERFLOW,       /* Two allocators. Use A first; failover to B */
    55         -  SQLITE4_MM_COMPACT,        /* Like memsys3 from SQLite3 */
    56         -  SQLITE4_MM_ROBSON,         /* Like memsys5 from SQLite3 */
    57         -  SQLITE4_MM_LINEAR,         /* Allocate from a fixed buffer w/o free */
           72  +  SQLITE4_MM_SYSTEM = 1,     /* Use the system malloc() */
           73  +  SQLITE4_MM_ONESIZE = 2,    /* All allocations map to a fixed size */
           74  +  SQLITE4_MM_OVERFLOW = 3,   /* Two allocators. Use A first; failover to B */
           75  +  SQLITE4_MM_COMPACT = 4,    /* Like memsys3 from SQLite3 */
           76  +  SQLITE4_MM_ROBSON = 5,     /* Like memsys5 from SQLite3 */
           77  +  SQLITE4_MM_LINEAR = 6,     /* Allocate from a fixed buffer w/o free */
           78  +  SQLITE4_MM_BESPOKE = 7,    /* Caller-defined implementation */
    58     79     SQLITE4_MM_DEBUG,          /* Debugging memory allocator */
    59         -  SQLITE4_MM_STATS,          /* Keep memory statistics */
    60         -  SQLITE4_MM_BESPOKE         /* Caller-defined implementation */
           80  +  SQLITE4_MM_STATS           /* Keep memory statistics */
    61     81   } sqlite4_mm_type;
    62     82   
    63     83   /*
    64     84   ** Allocate a new memory manager.  Return NULL if unable.
    65     85   */
    66     86   sqlite4_mm *sqlite4_mm_new(sqlite4_mm_type, ...);
    67     87   
................................................................................
   103    123   /*
   104    124   ** Enable or disable benign failure mode.  Benign failure mode can be
   105    125   ** nested.  In benign failure mode, OOM errors do not necessarily propagate
   106    126   ** back out to the application but can be dealt with internally.  Memory
   107    127   ** allocations that occur in benign failure mode are considered "optional".
   108    128   */
   109    129   void sqlite4_mm_benign_failures(sqlite4_mm*, int bEnable);
          130  +
          131  +/*
          132  +** Rest

Changes to src/pragma.c.

    73     73   #ifdef SQLITE4_DEBUG
    74     74       { "sql_trace",                SQLITE4_SqlTrace      },
    75     75       { "vdbe_listing",             SQLITE4_VdbeListing   },
    76     76       { "vdbe_trace",               SQLITE4_VdbeTrace     },
    77     77       { "kv_trace",                 SQLITE4_KvTrace       },
    78     78       { "trace",                    SQLITE4_SqlTrace | SQLITE4_VdbeListing |
    79     79                                     SQLITE4_VdbeTrace | SQLITE4_KvTrace },
           80  +    { "vdbe_addoptrace",          SQLITE4_VdbeAddopTrace },
    80     81   #endif
    81     82   #ifndef SQLITE4_OMIT_CHECK
    82     83       { "ignore_check_constraints", SQLITE4_IgnoreChecks  },
    83     84   #endif
    84     85       /* The following is VERY experimental */
    85     86       { "writable_schema",          SQLITE4_WriteSchema|SQLITE4_RecoveryMode },
    86     87   

Changes to src/resolve.c.

   338    338       ** we have a match (cnt>0) or when we run out of name contexts.
   339    339       */
   340    340       if( cnt==0 ){
   341    341         pNC = pNC->pNext;
   342    342       }
   343    343     }
   344    344   
   345         -  /*
   346         -  ** If X and Y are NULL (in other words if only the column name Z is
   347         -  ** supplied) and the value of Z is enclosed in double-quotes, then
   348         -  ** Z is a string literal if it doesn't match any column names.  In that
   349         -  ** case, we need to return right away and not make any changes to
   350         -  ** pExpr.
   351         -  **
   352         -  ** Because no reference was made to outer contexts, the pNC->nRef
   353         -  ** fields are not changed in any context.
   354         -  */
   355         -  if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
   356         -    pExpr->op = TK_STRING;
   357         -    pExpr->pTab = 0;
   358         -    return WRC_Prune;
   359         -  }
   360         -
   361    345     /*
   362    346     ** cnt==0 means there was not match.  cnt>1 means there were two or
   363    347     ** more matches.  Either way, we have an error.
   364    348     */
   365    349     if( cnt!=1 ){
   366    350       const char *zErr;
   367    351       zErr = cnt==0 ? "no such column" : "ambiguous column name";

Changes to src/select.c.

   944    944     if( p->selFlags & SF_UseSorter ){
   945    945       int regSortOut = ++pParse->nMem;
   946    946       int ptab2 = pParse->nTab++;
   947    947       sqlite4VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2);
   948    948       addr = 1 + sqlite4VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
   949    949       codeOffset(v, p, addrContinue);
   950    950       sqlite4VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
   951         -    sqlite4VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow);
          951  +    sqlite4VdbeAddOp3(v, OP_Column, ptab2, 0, regRow);
   952    952       sqlite4VdbeChangeP5(v, OPFLAG_CLEARCACHE);
   953    953     }else{
   954    954       addr = 1 + sqlite4VdbeAddOp2(v, OP_Sort, iTab, addrBreak);
   955    955       codeOffset(v, p, addrContinue);
   956         -    /* sqlite4VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow); */
          956  +    sqlite4VdbeAddOp3(v, OP_Column, iTab, 0, regRow);
   957    957     }
   958    958     switch( eDest ){
   959    959       case SRT_Table:
   960    960       case SRT_EphemTab: {
   961    961         testcase( eDest==SRT_Table );
   962    962         testcase( eDest==SRT_EphemTab );
   963    963         sqlite4VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
................................................................................
  1278   1278     int cnt;                    /* Index added to make the name unique */
  1279   1279     Column *aCol, *pCol;        /* For looping over result columns */
  1280   1280     int nCol;                   /* Number of columns in the result set */
  1281   1281     Expr *p;                    /* Expression for a single result column */
  1282   1282     char *zName;                /* Column name */
  1283   1283     int nName;                  /* Size of name in zName[] */
  1284   1284   
  1285         -  *pnCol = nCol = pEList->nExpr;
         1285  +  *pnCol = nCol = pEList ? pEList->nExpr : 0;
  1286   1286     aCol = *paCol = sqlite4DbMallocZero(db, sizeof(aCol[0])*nCol);
  1287   1287     if( aCol==0 ) return SQLITE4_NOMEM;
  1288   1288     for(i=0, pCol=aCol; i<nCol; i++, pCol++){
  1289   1289       /* Get an appropriate name for the column
  1290   1290       */
  1291   1291       p = pEList->a[i].pExpr;
  1292   1292       assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
................................................................................
  2305   2305     ** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL).
  2306   2306     */
  2307   2307     if( op==TK_ALL ){
  2308   2308       regPrev = 0;
  2309   2309     }else{
  2310   2310       int nExpr = p->pEList->nExpr;
  2311   2311       assert( nOrderBy>=nExpr || db->mallocFailed );
  2312         -    regPrev = sqlite4GetTempRange(pParse, nExpr+1);
         2312  +    regPrev = pParse->nMem + 1;
         2313  +    pParse->nMem += nExpr + 1;
  2313   2314       sqlite4VdbeAddOp2(v, OP_Integer, 0, regPrev);
  2314   2315       pKeyDup = sqlite4DbMallocZero(db,
  2315   2316                     sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
  2316   2317       if( pKeyDup ){
  2317   2318         pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
  2318   2319         pKeyDup->nField = (u16)nExpr;
  2319   2320         pKeyDup->enc = ENC(db);
................................................................................
  2486   2487     */
  2487   2488     sqlite4VdbeResolveLabel(v, labelCmpr);
  2488   2489     sqlite4VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
  2489   2490     sqlite4VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, nOrderBy,
  2490   2491                            (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
  2491   2492     sqlite4VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
  2492   2493   
  2493         -  /* Release temporary registers
  2494         -  */
  2495         -  if( regPrev ){
  2496         -    sqlite4ReleaseTempRange(pParse, regPrev, nOrderBy+1);
  2497         -  }
  2498         -
  2499   2494     /* Jump to the this point in order to terminate the query.
  2500   2495     */
  2501   2496     sqlite4VdbeResolveLabel(v, labelEnd);
  2502   2497   
  2503   2498     /* Set the number of output columns
  2504   2499     */
  2505   2500     if( pDest->eDest==SRT_Output ){
................................................................................
  2699   2694   **        operator other than UNION ALL because all the other compound
  2700   2695   **        operators have an implied DISTINCT which is disallowed by
  2701   2696   **        restriction (4).
  2702   2697   **
  2703   2698   **  (18)  If the sub-query is a compound select, then all terms of the
  2704   2699   **        ORDER by clause of the parent must be simple references to 
  2705   2700   **        columns of the sub-query.
         2701  +**
         2702  +**        Also, each component of the sub-query must return the same number
         2703  +**        of result columns. This is actually a requirement for any compound
         2704  +**        SELECT statement, but all the code here does is make sure that no
         2705  +**        such (illegal) sub-query is flattened. The caller will detect the
         2706  +**        syntax error and return a detailed message.
  2706   2707   **
  2707   2708   **  (19)  The subquery does not use LIMIT or the outer query does not
  2708   2709   **        have a WHERE clause.
  2709   2710   **
  2710   2711   **  (20)  If the sub-query is a compound select, then it must not use
  2711   2712   **        an ORDER BY clause.  Ticket #3773.  We could relax this constraint
  2712   2713   **        somewhat by saying that the terms of the ORDER BY clause must
................................................................................
  2839   2840       for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
  2840   2841         testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
  2841   2842         testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
  2842   2843         assert( pSub->pSrc!=0 );
  2843   2844         if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0
  2844   2845          || (pSub1->pPrior && pSub1->op!=TK_ALL) 
  2845   2846          || pSub1->pSrc->nSrc<1
         2847  +       || pSub->pEList->nExpr!=pSub1->pEList->nExpr
  2846   2848         ){
  2847   2849           return 0;
  2848   2850         }
  2849   2851         testcase( pSub1->pSrc->nSrc>1 );
  2850   2852       }
  2851   2853   
  2852   2854       /* Restriction 18. */

Changes to src/shell.c.

   317    317     int argc,
   318    318     sqlite4_value **argv
   319    319   ){
   320    320     assert( 0==argc );
   321    321     assert( zShellStatic );
   322    322     UNUSED_PARAMETER(argc);
   323    323     UNUSED_PARAMETER(argv);
   324         -  sqlite4_result_text(context, zShellStatic, -1, SQLITE4_STATIC);
          324  +  sqlite4_result_text(context, zShellStatic, -1, SQLITE4_STATIC, 0);
   325    325   }
   326    326   
   327    327   
   328    328   /*
   329    329   ** This routine reads a line of text from FILE in, stores
   330    330   ** the text in memory obtained from malloc() and returns a pointer
   331    331   ** to the text.  NULL is returned at end of file, or if malloc()
................................................................................
  1803   1803             int k;
  1804   1804             for(z=azCol[i], j=1, k=0; z[j]; j++){
  1805   1805               if( z[j]=='"' ){ j++; if( z[j]==0 ) break; }
  1806   1806               z[k++] = z[j];
  1807   1807             }
  1808   1808             z[k] = 0;
  1809   1809           }
  1810         -        sqlite4_bind_text(pStmt, i+1, azCol[i], -1, SQLITE4_STATIC);
         1810  +        sqlite4_bind_text(pStmt, i+1, azCol[i], -1, SQLITE4_STATIC, 0);
  1811   1811         }
  1812   1812         sqlite4_step(pStmt);
  1813   1813         rc = sqlite4_reset(pStmt);
  1814   1814         free(zLine);
  1815   1815         if( rc!=SQLITE4_OK ){
  1816   1816           fprintf(stderr,"Error: %s\n", sqlite4_errmsg(db));
  1817   1817           zCommit = "ROLLBACK";
................................................................................
  2168   2168       zSql = sqlite4_mprintf(0, "%z ORDER BY 1", zSql);
  2169   2169       rc = sqlite4_prepare(p->db, zSql, -1, &pStmt, 0);
  2170   2170       sqlite4_free(0, zSql);
  2171   2171       if( rc ) return rc;
  2172   2172       nRow = nAlloc = 0;
  2173   2173       azResult = 0;
  2174   2174       if( nArg>1 ){
  2175         -      sqlite4_bind_text(pStmt, 1, azArg[1], -1, SQLITE4_TRANSIENT);
         2175  +      sqlite4_bind_text(pStmt, 1, azArg[1], -1, SQLITE4_TRANSIENT, 0);
  2176   2176       }else{
  2177         -      sqlite4_bind_text(pStmt, 1, "%", -1, SQLITE4_STATIC);
         2177  +      sqlite4_bind_text(pStmt, 1, "%", -1, SQLITE4_STATIC, 0);
  2178   2178       }
  2179   2179       while( sqlite4_step(pStmt)==SQLITE4_ROW ){
  2180   2180         if( nRow>=nAlloc ){
  2181   2181           char **azNew;
  2182   2182           int n = nAlloc*2 + 10;
  2183   2183           azNew = sqlite4_realloc(0, azResult, sizeof(azResult[0])*n);
  2184   2184           if( azNew==0 ){

Changes to src/sqlite.h.in.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** This header file defines the interface that the SQLite library
           12  +**
           13  +** This header file defines the interface that the SQLite4 library
    13     14   ** presents to client programs.  If a C-function, structure, datatype,
    14     15   ** or constant definition does not appear in this file, then it is
    15     16   ** not a published API of SQLite, is subject to change without
    16     17   ** notice, and should not be referenced by programs that use SQLite.
    17     18   **
    18         -** Some of the definitions that are in this file are marked as
    19         -** "experimental".  Experimental interfaces are normally new
    20         -** features recently added to SQLite.  We do not anticipate changes
    21         -** to experimental interfaces but reserve the right to make minor changes
    22         -** if experience from use "in the wild" suggest such changes are prudent.
    23         -**
    24         -** The official C-language API documentation for SQLite is derived
    25         -** from comments in this file.  This file is the authoritative source
    26         -** on how SQLite interfaces are suppose to operate.
    27         -**
    28     19   ** The name of this file under configuration management is "sqlite.h.in".
    29     20   ** The makefile makes some minor changes to this file (such as inserting
    30     21   ** the version number) and changes its name to "sqlite4.h" as
    31     22   ** part of the build process.
    32     23   */
    33     24   #ifndef _SQLITE4_H_
    34     25   #define _SQLITE4_H_
................................................................................
    45     36   /*
    46     37   ** Add the ability to override 'extern'
    47     38   */
    48     39   #ifndef SQLITE4_EXTERN
    49     40   # define SQLITE4_EXTERN extern
    50     41   #endif
    51     42   
    52         -/*
    53         -** These no-op macros are used in front of interfaces to mark those
    54         -** interfaces as either deprecated or experimental.  New applications
    55         -** should not use deprecated interfaces - they are support for backwards
    56         -** compatibility only.  Application writers should be aware that
    57         -** experimental interfaces are subject to change in point releases.
    58         -**
    59         -** These macros used to resolve to various kinds of compiler magic that
    60         -** would generate warning messages when they were used.  But that
    61         -** compiler magic ended up generating such a flurry of bug reports
    62         -** that we have taken it all out and gone back to using simple
    63         -** noop macros.
    64         -*/
    65         -#define SQLITE4_DEPRECATED
    66         -#define SQLITE4_EXPERIMENTAL
    67         -
    68     43   /*
    69     44   ** Ensure these symbols were not defined by some previous header file.
    70     45   */
    71     46   #ifdef SQLITE4_VERSION
    72     47   # undef SQLITE4_VERSION
    73     48   #endif
    74     49   #ifdef SQLITE4_VERSION_NUMBER
    75     50   # undef SQLITE4_VERSION_NUMBER
    76     51   #endif
           52  +
           53  +/*
           54  +** CAPIREF: 64-Bit Integer Types
           55  +** KEYWORDS: sqlite4_int64 sqlite4_uint64
           56  +**
           57  +** Because there is no cross-platform way to specify 64-bit integer types
           58  +** SQLite includes typedefs for 64-bit signed and unsigned integers.
           59  +**
           60  +** ^The sqlite4_int64 and sqlite_int64 types can store integer values
           61  +** between -9223372036854775808 and +9223372036854775807 inclusive.  ^The
           62  +** sqlite4_uint64 and sqlite_uint64 types can store integer values 
           63  +** between 0 and +18446744073709551615 inclusive.
           64  +*/
           65  +#ifdef SQLITE4_INT64_TYPE
           66  +  typedef SQLITE4_INT64_TYPE sqlite4_int64_t;
           67  +  typedef unsigned SQLITE4_INT64_TYPE sqlite4_uint64_t;
           68  +#elif defined(_MSC_VER) || defined(__BORLANDC__)
           69  +  typedef __int64 sqlite4_int64_t;
           70  +  typedef unsigned __int64 sqlite4_uint64_t;
           71  +#else
           72  +  typedef long long int sqlite4_int64_t;
           73  +  typedef unsigned long long int sqlite4_uint64_t;
           74  +#endif
           75  +typedef sqlite4_int64_t sqlite4_int64;
           76  +typedef sqlite4_uint64_t sqlite4_uint64;
           77  +
           78  +/*
           79  +** CAPIREF: String length type
           80  +**
           81  +** A type for measuring the length of the string.  Like size_t but
           82  +** does not require &lt;stddef.h&gt;
           83  +*/
           84  +typedef int sqlite4_size_t;
           85  +
           86  +/*
           87  +** Available memory allocator object subtypes:
           88  +*/
           89  +typedef enum {
           90  +  SQLITE4_MM_SYSTEM = 1,     /* Use the system malloc() */
           91  +  SQLITE4_MM_ONESIZE = 2,    /* All allocations map to a fixed size */
           92  +  SQLITE4_MM_OVERFLOW = 3,   /* Two allocators. Use A first; failover to B */
           93  +  SQLITE4_MM_COMPACT = 4,    /* Like memsys3 from SQLite3 */
           94  +  SQLITE4_MM_ROBSON = 5,     /* Like memsys5 from SQLite3 */
           95  +  SQLITE4_MM_LINEAR = 6,     /* Allocate from a fixed buffer w/o free */
           96  +  SQLITE4_MM_BESPOKE = 7,    /* Caller-defined implementation */
           97  +  SQLITE4_MM_DEBUG,          /* Debugging memory allocator */
           98  +  SQLITE4_MM_STATS           /* Keep memory statistics */
           99  +} sqlite4_mm_type;
          100  +
          101  +/*
          102  +** Base class for the memory allocator object.
          103  +**
          104  +** Implementations may extend this with additional
          105  +** fields specific to its own needs.  This needs to be public so that
          106  +** applications can supply their on customized memory allocators.
          107  +*/
          108  +typedef struct sqlite4_mm sqlite4_mm;
          109  +typedef struct sqlite4_mm_methods sqlite4_mm_methods;
          110  +struct sqlite4_mm {
          111  +  const struct sqlite4_mm_methods *pMethods;
          112  +};
          113  +struct sqlite4_mm_methods {
          114  +  int iVersion;
          115  +  void *(*xMalloc)(sqlite4_mm*, sqlite4_size_t);
          116  +  void *(*xRealloc)(sqlite4_mm*, void*, sqlite4_size_t);
          117  +  void (*xFree)(sqlite4_mm*, void*);
          118  +  sqlite4_size_t (*xMsize)(sqlite4_mm*, void*);
          119  +  int (*xMember)(sqlite4_mm*, const void*);
          120  +  void (*xBenign)(sqlite4_mm*, int);
          121  +  sqlite4_int64 (*xStat)(sqlite4_mm*, unsigned eType, unsigned bFlags);
          122  +  int (*xCtrl)(sqlite4_mm*, unsigned eType, va_list);
          123  +  void (*xFinal)(sqlite4_mm*);
          124  +};
          125  +
          126  +/*
          127  +** Return a pointer to the default memory allocator, which is basically
          128  +** a wrapper around system malloc()/realloc()/free().
          129  +*/
          130  +sqlite4_mm *sqlite4_mm_default(void);
          131  +
          132  +
          133  +/*
          134  +** Create a new memory allocator object.
          135  +*/
          136  +sqlite4_mm *sqlite4_mm_new(sqlite4_mm_type, ...);
          137  +
          138  +
          139  +/*
          140  +** Allocate a new memory manager.  Return NULL if unable.
          141  +*/
          142  +sqlite4_mm *sqlite4_mm_new(sqlite4_mm_type, ...);
          143  +
          144  +/*
          145  +** Free the sqlite4_mm object.
          146  +**
          147  +** All outstanding memory for the allocator must be freed prior to
          148  +** invoking this interface, or else the behavior is undefined.
          149  +*/
          150  +void sqlite4_mm_destroy(sqlite4_mm*);
          151  +
          152  +/*
          153  +** Core memory allocation routines:
          154  +*/
          155  +void *sqlite4_mm_malloc(sqlite4_mm*, sqlite4_size_t);
          156  +void *sqlite4_mm_realloc(sqlite4_mm*, void*, sqlite4_size_t);
          157  +void sqlite4_mm_free(sqlite4_mm*, void*);
          158  +
          159  +/*
          160  +** Return the size of a memory allocation.
          161  +**
          162  +** All memory allocators in SQLite4 must be able to report their size.
          163  +** When using system malloc() on system that lack the malloc_usable_size()
          164  +** routine or its equivalent, then the sqlite4_mm object allocates 8 extra
          165  +** bytes for each memory allocation and stores the allocation size in those
          166  +** initial 8 bytes.
          167  +*/
          168  +sqlite4_size_t sqlite4_mm_msize(sqlite4_mm*, void*);
          169  +
          170  +/*
          171  +** Check to see if pOld is a memory allocation from pMM.  If it is, return
          172  +** 1.  If not, return 0.  If we cannot determine an answer, return -1.
          173  +**
          174  +** If pOld is not a valid memory allocation or is a memory allocation that
          175  +** has previously been freed, then the result of this routine is undefined.
          176  +*/
          177  +int sqlite4_mm_member(sqlite4_mm *pMM, const void *pOld);
          178  +
          179  +/*
          180  +** Allowed values for the second parameter ("eType") to sqlite4_mm_type().
          181  +*/
          182  +#define SQLITE4_MMSTAT_OUT        1
          183  +#define SQLITE4_MMSTAT_OUT_HW     2
          184  +#define SQLITE4_MMSTAT_UNITS      3
          185  +#define SQLITE4_MMSTAT_UNITS_HW   4
          186  +#define SQLITE4_MMSTAT_SIZE       5
          187  +#define SQLITE4_MMSTAT_SZFAULT    6
          188  +#define SQLITE4_MMSTAT_MEMFAULT   7
          189  +#define SQLITE4_MMSTAT_FAULT      8
          190  +
          191  +/*
          192  +** Bits for the bit vector third parameter ("flags") to sqlite4_mm_type()
          193  +*/
          194  +#define SQLITE4_MMSTAT_RESET      0x01
          195  +
          196  +/*
          197  +** Return statistics or status information about a memory allocator.
          198  +** Not all memory allocators provide all stat values.  Some memory
          199  +** allocators provides no states at all.  If a particular stat for
          200  +** a memory allocator is unavailable, then -1 is returned.
          201  +*/
          202  +sqlite4_int64 sqlite4_mm_stat(sqlite4_mm *pMM, int eType, unsigned flags);
          203  +
          204  +/*
          205  +** Send a control message into a memory allocator.
          206  +*/
          207  +int sqlit4_mm_control(sqlite4_mm *pMM, int eType, ...);
          208  +
          209  +/*
          210  +** Enable or disable benign failure mode.  Benign failure mode can be
          211  +** nested.  In benign failure mode, OOM errors do not necessarily propagate
          212  +** back out to the application but can be dealt with internally.  Memory
          213  +** allocations that occur in benign failure mode are considered "optional".
          214  +*/
          215  +void sqlite4_mm_benign_failures(sqlite4_mm*, int bEnable);
          216  +
    77    217   
    78    218   /*
    79    219   ** CAPIREF: Run-time Environment Object
    80    220   **
    81    221   ** An instance of the following object defines the run-time environment 
    82    222   ** for an SQLite4 database connection.  This object defines the interface
    83    223   ** to appropriate mutex routines, memory allocation routines, a
................................................................................
   250    390   ** is its destructor.  There are many other interfaces (such as
   251    391   ** [sqlite4_prepare], [sqlite4_create_function()], and
   252    392   ** [sqlite4_busy_timeout()] to name but three) that are methods on an
   253    393   ** sqlite4 object.
   254    394   */
   255    395   typedef struct sqlite4 sqlite4;
   256    396   
   257         -/*
   258         -** CAPIREF: 64-Bit Integer Types
   259         -** KEYWORDS: sqlite4_int64 sqlite4_uint64
   260         -**
   261         -** Because there is no cross-platform way to specify 64-bit integer types
   262         -** SQLite includes typedefs for 64-bit signed and unsigned integers.
   263         -**
   264         -** ^The sqlite4_int64 and sqlite_int64 types can store integer values
   265         -** between -9223372036854775808 and +9223372036854775807 inclusive.  ^The
   266         -** sqlite4_uint64 and sqlite_uint64 types can store integer values 
   267         -** between 0 and +18446744073709551615 inclusive.
   268         -*/
   269         -#ifdef SQLITE4_INT64_TYPE
   270         -  typedef SQLITE4_INT64_TYPE sqlite4_int64_t;
   271         -  typedef unsigned SQLITE4_INT64_TYPE sqlite4_uint64_t;
   272         -#elif defined(_MSC_VER) || defined(__BORLANDC__)
   273         -  typedef __int64 sqlite4_int64_t;
   274         -  typedef unsigned __int64 sqlite4_uint64_t;
   275         -#else
   276         -  typedef long long int sqlite4_int64_t;
   277         -  typedef unsigned long long int sqlite4_uint64_t;
   278         -#endif
   279         -typedef sqlite4_int64_t sqlite4_int64;
   280         -typedef sqlite4_uint64_t sqlite4_uint64;
   281         -
   282         -/*
   283         -** CAPIREF: String length type
   284         -**
   285         -** A type for measuring the length of the string.  Like size_t but
   286         -** does not require &lt;stddef.h&gt;
   287         -*/
   288         -typedef int sqlite4_size_t;
   289         -
   290    397   /*
   291    398   ** If compiling for a processor that lacks floating point support,
   292    399   ** substitute integer for floating-point.
   293    400   */
   294    401   #ifdef SQLITE4_OMIT_FLOATING_POINT
   295    402   # define double sqlite4_int64
   296    403   #endif
................................................................................
   737    844   ** </dl>
   738    845   */
   739    846   #define SQLITE4_DBCONFIG_LOOKASIDE       1001  /* void* int int */
   740    847   #define SQLITE4_DBCONFIG_ENABLE_FKEY     1002  /* int int* */
   741    848   #define SQLITE4_DBCONFIG_ENABLE_TRIGGER  1003  /* int int* */
   742    849   
   743    850   
   744         -/*
   745         -** CAPIREF: Last Insert Rowid
   746         -**
   747         -** ^The sqlite4_last_insert_rowid(D) routine returns the primary key value
   748         -** of the the most recent successful [INSERT] from [database connection] D
   749         -** into a table where the primary key of the inserted row is a single
   750         -** integer.
   751         -** ^If there have been no successful [INSERT]s of rows with a single integer
   752         -** PRIMARY KEY value on database connection D, then this routine returns
   753         -** zero.
   754         -**
   755         -** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
   756         -** method, then this routine will return the [rowid] of the inserted
   757         -** row as long as the trigger or virtual table method is running.
   758         -** But once the trigger or virtual table method ends, the value returned 
   759         -** by this routine reverts to what it was before the trigger or virtual
   760         -** table method began.)^
   761         -**
   762         -** ^An [INSERT] that fails due to a constraint violation is not a
   763         -** successful [INSERT] and does not change the value returned by this
   764         -** routine.  ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK,
   765         -** and INSERT OR ABORT make no changes to the return value of this
   766         -** routine when their insertion fails.  ^(When INSERT OR REPLACE
   767         -** encounters a constraint violation, it does not fail.  The
   768         -** INSERT continues to completion after deleting rows that caused
   769         -** the constraint problem so INSERT OR REPLACE will always change
   770         -** the return value of this interface.)^
   771         -**
   772         -** ^For the purposes of this routine, an [INSERT] is considered to
   773         -** be successful even if it is subsequently rolled back.
   774         -**
   775         -** This function is accessible to SQL statements via the
   776         -** [last_insert_rowid() SQL function].
   777         -**
   778         -** If a separate thread performs a new [INSERT] on the same
   779         -** database connection while the [sqlite4_last_insert_rowid()]
   780         -** function is running and thus changes the last insert [rowid],
   781         -** then the value returned by [sqlite4_last_insert_rowid()] is
   782         -** unpredictable and might not equal either the old or the new
   783         -** last insert [rowid].
   784         -*/
   785         -sqlite4_int64 sqlite4_last_insert_rowid(sqlite4*);
   786         -
   787    851   /*
   788    852   ** CAPIREF: Count The Number Of Rows Modified
   789    853   **
   790    854   ** ^This function returns the number of database rows that were changed
   791    855   ** or inserted or deleted by the most recently completed SQL statement
   792    856   ** on the [database connection] specified by the first parameter.
   793    857   ** ^(Only changes that are directly specified by the [INSERT], [UPDATE],
................................................................................
  1311   1375   ** is only capable of millisecond resolution so the six least significant
  1312   1376   ** digits in the time are meaningless.  Future versions of SQLite
  1313   1377   ** might provide greater resolution on the profiler callback.  The
  1314   1378   ** sqlite4_profile() function is considered experimental and is
  1315   1379   ** subject to change in future versions of SQLite.
  1316   1380   */
  1317   1381   void *sqlite4_trace(sqlite4*, void(*xTrace)(void*,const char*), void*);
  1318         -SQLITE4_EXPERIMENTAL void *sqlite4_profile(sqlite4*,
         1382  +void *sqlite4_profile(sqlite4*,
  1319   1383      void(*xProfile)(void*,const char*,sqlite4_uint64), void*);
  1320   1384   
  1321   1385   /*
  1322   1386   ** CAPIREF: Query Progress Callbacks
  1323   1387   **
  1324   1388   ** ^The sqlite4_progress_handler(D,N,X,P) interface causes the callback
  1325   1389   ** function X to be invoked periodically during long running calls to
................................................................................
  1803   1867   ** ^If the fifth argument is
  1804   1868   ** the special value [SQLITE4_STATIC], then SQLite assumes that the
  1805   1869   ** information is in static, unmanaged space and does not need to be freed.
  1806   1870   ** ^If the fifth argument has the value [SQLITE4_TRANSIENT], then
  1807   1871   ** SQLite makes its own private copy of the data immediately, before
  1808   1872   ** the sqlite4_bind_*() routine returns.
  1809   1873   **
  1810         -** ^The sqlite4_bind_zeroblob() routine binds a BLOB of length N that
  1811         -** is filled with zeroes.  ^A zeroblob uses a fixed amount of memory
  1812         -** (just an integer to hold its size) while it is being processed.
  1813         -** Zeroblobs are intended to serve as placeholders for BLOBs whose
  1814         -** content is later written using
  1815         -** [sqlite4_blob_open | incremental BLOB I/O] routines.
  1816         -** ^A negative value for the zeroblob results in a zero-length BLOB.
  1817         -**
  1818   1874   ** ^If any of the sqlite4_bind_*() routines are called with a NULL pointer
  1819   1875   ** for the [prepared statement] or with a prepared statement for which
  1820   1876   ** [sqlite4_step()] has been called more recently than [sqlite4_reset()],
  1821   1877   ** then the call will return [SQLITE4_MISUSE].  If any sqlite4_bind_()
  1822   1878   ** routine is passed a [prepared statement] that has been finalized, the
  1823   1879   ** result is undefined and probably harmful.
  1824   1880   **
................................................................................
  1829   1885   ** [error code] if anything goes wrong.
  1830   1886   ** ^[SQLITE4_RANGE] is returned if the parameter
  1831   1887   ** index is out of range.  ^[SQLITE4_NOMEM] is returned if malloc() fails.
  1832   1888   **
  1833   1889   ** See also: [sqlite4_bind_parameter_count()],
  1834   1890   ** [sqlite4_bind_parameter_name()], and [sqlite4_bind_parameter_index()].
  1835   1891   */
  1836         -int sqlite4_bind_blob(sqlite4_stmt*, int, const void*, int n, void(*)(void*));
         1892  +int sqlite4_bind_blob(sqlite4_stmt*, int, const void*, int n, 
         1893  +                      void(*)(void*,void*),void*);
  1837   1894   int sqlite4_bind_double(sqlite4_stmt*, int, double);
  1838   1895   int sqlite4_bind_int(sqlite4_stmt*, int, int);
  1839   1896   int sqlite4_bind_int64(sqlite4_stmt*, int, sqlite4_int64);
  1840   1897   int sqlite4_bind_null(sqlite4_stmt*, int);
  1841         -int sqlite4_bind_text(sqlite4_stmt*, int, const char*, int n, void(*)(void*));
  1842         -int sqlite4_bind_text16(sqlite4_stmt*, int, const void*, int, void(*)(void*));
         1898  +int sqlite4_bind_text(sqlite4_stmt*, int, const char*, int n,
         1899  +                      void(*)(void*,void*),void*);
         1900  +int sqlite4_bind_text16(sqlite4_stmt*, int, const void*, int,
         1901  +                        void(*)(void*,void*),void*);
  1843   1902   int sqlite4_bind_value(sqlite4_stmt*, int, const sqlite4_value*);
  1844         -int sqlite4_bind_zeroblob(sqlite4_stmt*, int, int n);
  1845   1903   
  1846   1904   /*
  1847   1905   ** CAPIREF: Number Of SQL Parameters
  1848   1906   **
  1849   1907   ** ^This routine can be used to find the number of [SQL parameters]
  1850   1908   ** in a [prepared statement].  SQL parameters are tokens of the
  1851   1909   ** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
................................................................................
  2146   2204   ** If [sqlite4_step()] or [sqlite4_reset()] or [sqlite4_finalize()]
  2147   2205   ** are called from a different thread while any of these routines
  2148   2206   ** are pending, then the results are undefined.
  2149   2207   **
  2150   2208   ** ^The sqlite4_column_type() routine returns the
  2151   2209   ** [SQLITE4_INTEGER | datatype code] for the initial data type
  2152   2210   ** of the result column.  ^The returned value is one of [SQLITE4_INTEGER],
  2153         -** [SQLITE4_FLOAT], [SQLITE4_TEXT], [SQLITE4_BLOB], or [SQLITE4_NULL].  The value
         2211  +** [SQLITE4_FLOAT], [SQLITE4_TEXT], [SQLITE4_BLOB], or [SQLITE4_NULL].
         2212  +** The value
  2154   2213   ** returned by sqlite4_column_type() is only meaningful if no type
  2155   2214   ** conversions have occurred as described below.  After a type conversion,
  2156   2215   ** the value returned by sqlite4_column_type() is undefined.  Future
  2157   2216   ** versions of SQLite may change the behavior of sqlite4_column_type()
  2158   2217   ** following a type conversion.
  2159   2218   **
  2160   2219   ** ^If the result is a BLOB or UTF-8 string then the sqlite4_column_bytes()
................................................................................
  2475   2534   #define SQLITE4_UTF8           1
  2476   2535   #define SQLITE4_UTF16LE        2
  2477   2536   #define SQLITE4_UTF16BE        3
  2478   2537   #define SQLITE4_UTF16          4    /* Use native byte order */
  2479   2538   #define SQLITE4_ANY            5    /* sqlite4_create_function only */
  2480   2539   #define SQLITE4_UTF16_ALIGNED  8    /* sqlite4_create_collation only */
  2481   2540   
  2482         -/*
  2483         -** CAPIREF: Deprecated Functions
  2484         -** DEPRECATED
  2485         -**
  2486         -** These functions are [deprecated].  In order to maintain
  2487         -** backwards compatibility with older code, these functions continue 
  2488         -** to be supported.  However, new applications should avoid
  2489         -** the use of these functions.  To help encourage people to avoid
  2490         -** using these functions, we are not going to tell you what they do.
  2491         -*/
  2492         -#ifndef SQLITE4_OMIT_DEPRECATED
  2493         -SQLITE4_DEPRECATED int sqlite4_aggregate_count(sqlite4_context*);
  2494         -SQLITE4_DEPRECATED int sqlite4_expired(sqlite4_stmt*);
  2495         -SQLITE4_DEPRECATED int sqlite4_transfer_bindings(sqlite4_stmt*, sqlite4_stmt*);
  2496         -SQLITE4_DEPRECATED int sqlite4_global_recover(void);
  2497         -#endif
  2498         -
  2499   2541   /*
  2500   2542   ** CAPIREF: Obtaining SQL Function Parameter Values
  2501   2543   **
  2502   2544   ** The C-language implementation of SQL functions and aggregates uses
  2503   2545   ** this set of interface routines to access the parameter values on
  2504   2546   ** the function or aggregate.
  2505   2547   **
................................................................................
  2660   2702   ** expressions that are constant at compile time. This includes literal
  2661   2703   ** values and [parameters].)^
  2662   2704   **
  2663   2705   ** These routines must be called from the same thread in which
  2664   2706   ** the SQL function is running.
  2665   2707   */
  2666   2708   void *sqlite4_get_auxdata(sqlite4_context*, int N);
  2667         -void sqlite4_set_auxdata(sqlite4_context*, int N, void*, void (*)(void*));
         2709  +void sqlite4_set_auxdata(sqlite4_context*, int N, void*,
         2710  +                         void (*)(void*,void*),void*);
  2668   2711   
  2669   2712   
  2670   2713   /*
  2671   2714   ** CAPIREF: Constants Defining Special Destructor Behavior
  2672   2715   **
  2673   2716   ** These are special values for the destructor that is passed in as the
  2674   2717   ** final argument to routines like [sqlite4_result_blob()].  ^If the destructor
................................................................................
  2677   2720   ** SQLITE4_TRANSIENT value means that the content will likely change in
  2678   2721   ** the near future and that SQLite should make its own private copy of
  2679   2722   ** the content before returning.
  2680   2723   **
  2681   2724   ** The typedef is necessary to work around problems in certain
  2682   2725   ** C++ compilers.  See ticket #2191.
  2683   2726   */
  2684         -typedef void (*sqlite4_destructor_type)(void*);
  2685         -void sqlite4_dynamic(void*);
         2727  +typedef void (*sqlite4_destructor_type)(void*,void*);
         2728  +void sqlite4_dynamic(void*,void*);
  2686   2729   #define SQLITE4_STATIC      ((sqlite4_destructor_type)0)
  2687   2730   #define SQLITE4_TRANSIENT   ((sqlite4_destructor_type)-1)
  2688   2731   #define SQLITE4_DYNAMIC     (sqlite4_dynamic)
  2689   2732   
  2690   2733   
  2691   2734   /*
  2692   2735   ** CAPIREF: Setting The Result Of An SQL Function
................................................................................
  2701   2744   ** Refer to the [SQL parameter] documentation for additional information.
  2702   2745   **
  2703   2746   ** ^The sqlite4_result_blob() interface sets the result from
  2704   2747   ** an application-defined function to be the BLOB whose content is pointed
  2705   2748   ** to by the second parameter and which is N bytes long where N is the
  2706   2749   ** third parameter.
  2707   2750   **
  2708         -** ^The sqlite4_result_zeroblob() interfaces set the result of
  2709         -** the application-defined function to be a BLOB containing all zero
  2710         -** bytes and N bytes in size, where N is the value of the 2nd parameter.
  2711         -**
  2712   2751   ** ^The sqlite4_result_double() interface sets the result from
  2713   2752   ** an application-defined function to be a floating point value specified
  2714   2753   ** by its 2nd argument.
  2715   2754   **
  2716   2755   ** ^The sqlite4_result_error() and sqlite4_result_error16() functions
  2717   2756   ** cause the implemented SQL function to throw an exception.
  2718   2757   ** ^SQLite uses the string pointed to by the
................................................................................
  2728   2767   ** bytes (not characters) from the 2nd parameter as the error message.
  2729   2768   ** ^The sqlite4_result_error() and sqlite4_result_error16()
  2730   2769   ** routines make a private copy of the error message text before
  2731   2770   ** they return.  Hence, the calling function can deallocate or
  2732   2771   ** modify the text after they return without harm.
  2733   2772   ** ^The sqlite4_result_error_code() function changes the error code
  2734   2773   ** returned by SQLite as a result of an error in a function.  ^By default,
  2735         -** the error code is SQLITE4_ERROR.  ^A subsequent call to sqlite4_result_error()
         2774  +** the error code is SQLITE4_ERROR.
         2775  +** ^A subsequent call to sqlite4_result_error()
  2736   2776   ** or sqlite4_result_error16() resets the error code to SQLITE4_ERROR.
  2737   2777   **
  2738   2778   ** ^The sqlite4_result_toobig() interface causes SQLite to throw an error
  2739   2779   ** indicating that a string or BLOB is too long to represent.
  2740   2780   **
  2741   2781   ** ^The sqlite4_result_nomem() interface causes SQLite to throw an error
  2742   2782   ** indicating that a memory allocation failed.
................................................................................
  2794   2834   ** [unprotected sqlite4_value] object is required, so either
  2795   2835   ** kind of [sqlite4_value] object can be used with this interface.
  2796   2836   **
  2797   2837   ** If these routines are called from within the different thread
  2798   2838   ** than the one containing the application-defined function that received
  2799   2839   ** the [sqlite4_context] pointer, the results are undefined.
  2800   2840   */
  2801         -void sqlite4_result_blob(sqlite4_context*, const void*, int, void(*)(void*));
         2841  +void sqlite4_result_blob(sqlite4_context*, const void*, int,
         2842  +                         void(*)(void*,void*),void*);
  2802   2843   void sqlite4_result_double(sqlite4_context*, double);
  2803   2844   void sqlite4_result_error(sqlite4_context*, const char*, int);
  2804   2845   void sqlite4_result_error16(sqlite4_context*, const void*, int);
  2805   2846   void sqlite4_result_error_toobig(sqlite4_context*);
  2806   2847   void sqlite4_result_error_nomem(sqlite4_context*);
  2807   2848   void sqlite4_result_error_code(sqlite4_context*, int);
  2808   2849   void sqlite4_result_int(sqlite4_context*, int);
  2809   2850   void sqlite4_result_int64(sqlite4_context*, sqlite4_int64);
  2810   2851   void sqlite4_result_null(sqlite4_context*);
  2811         -void sqlite4_result_text(sqlite4_context*, const char*, int, void(*)(void*));
  2812         -void sqlite4_result_text16(sqlite4_context*, const void*, int, void(*)(void*));
  2813         -void sqlite4_result_text16le(sqlite4_context*, const void*, int,void(*)(void*));
  2814         -void sqlite4_result_text16be(sqlite4_context*, const void*, int,void(*)(void*));
         2852  +void sqlite4_result_text(sqlite4_context*, const char*, int,
         2853  +                         void(*)(void*,void*),void*);
         2854  +void sqlite4_result_text16(sqlite4_context*, const void*, int,
         2855  +                           void(*)(void*,void*),void*);
         2856  +void sqlite4_result_text16le(sqlite4_context*, const void*, int,
         2857  +                             void(*)(void*,void*),void*);
         2858  +void sqlite4_result_text16be(sqlite4_context*, const void*, int,
         2859  +                             void(*)(void*,void*),void*);
  2815   2860   void sqlite4_result_value(sqlite4_context*, sqlite4_value*);
  2816         -void sqlite4_result_zeroblob(sqlite4_context*, int n);
  2817   2861   
  2818   2862   /*
  2819   2863   ** CAPIREF: Define New Collating Sequences
  2820   2864   **
  2821   2865   ** ^This function adds, removes, or modifies a [collation] associated
  2822   2866   ** with the [database connection] specified as the first argument.
  2823   2867   **
................................................................................
  3856   3900   ** New verbs may be added in future releases of SQLite. Existing verbs
  3857   3901   ** might be discontinued. Applications should check the return code from
  3858   3902   ** [sqlite4_db_status()] to make sure that the call worked.
  3859   3903   ** The [sqlite4_db_status()] interface will return a non-zero error code
  3860   3904   ** if a discontinued or unsupported verb is invoked.
  3861   3905   **
  3862   3906   ** <dl>
  3863         -** [[SQLITE4_DBSTATUS_LOOKASIDE_USED]] ^(<dt>SQLITE4_DBSTATUS_LOOKASIDE_USED</dt>
         3907  +** [[SQLITE4_DBSTATUS_LOOKASIDE_USED]]
         3908  +** ^(<dt>SQLITE4_DBSTATUS_LOOKASIDE_USED</dt>
  3864   3909   ** <dd>This parameter returns the number of lookaside memory slots currently
  3865   3910   ** checked out.</dd>)^
  3866   3911   **
  3867   3912   ** [[SQLITE4_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE4_DBSTATUS_LOOKASIDE_HIT</dt>
  3868   3913   ** <dd>This parameter returns the number malloc attempts that were 
  3869   3914   ** satisfied using lookaside memory. Only the high-water value is meaningful;
  3870   3915   ** the current value is always zero.)^
................................................................................
  3961   4006   ** KEYWORDS: {SQLITE4_STMTSTATUS counter} {SQLITE4_STMTSTATUS counters}
  3962   4007   **
  3963   4008   ** These preprocessor macros define integer codes that name counter
  3964   4009   ** values associated with the [sqlite4_stmt_status()] interface.
  3965   4010   ** The meanings of the various counters are as follows:
  3966   4011   **
  3967   4012   ** <dl>
  3968         -** [[SQLITE4_STMTSTATUS_FULLSCAN_STEP]] <dt>SQLITE4_STMTSTATUS_FULLSCAN_STEP</dt>
         4013  +** [[SQLITE4_STMTSTATUS_FULLSCAN_STEP]]
         4014  +** <dt>SQLITE4_STMTSTATUS_FULLSCAN_STEP</dt>
  3969   4015   ** <dd>^This is the number of times that SQLite has stepped forward in
  3970   4016   ** a table as part of a full table scan.  Large numbers for this counter
  3971   4017   ** may indicate opportunities for performance improvement through 
  3972   4018   ** careful use of indices.</dd>
  3973   4019   **
  3974   4020   ** [[SQLITE4_STMTSTATUS_SORT]] <dt>SQLITE4_STMTSTATUS_SORT</dt>
  3975   4021   ** <dd>^This is the number of sort operations that have occurred.
................................................................................
  3984   4030   ** need to be reinitialized each time the statement is run.</dd>
  3985   4031   ** </dl>
  3986   4032   */
  3987   4033   #define SQLITE4_STMTSTATUS_FULLSCAN_STEP     1
  3988   4034   #define SQLITE4_STMTSTATUS_SORT              2
  3989   4035   #define SQLITE4_STMTSTATUS_AUTOINDEX         3
  3990   4036   
  3991         -
  3992         -/*
  3993         -** CAPIREF: Unlock Notification
  3994         -**
  3995         -** ^When running in shared-cache mode, a database operation may fail with
  3996         -** an [SQLITE4_LOCKED] error if the required locks on the shared-cache or
  3997         -** individual tables within the shared-cache cannot be obtained. See
  3998         -** [SQLite Shared-Cache Mode] for a description of shared-cache locking. 
  3999         -** ^This API may be used to register a callback that SQLite will invoke 
  4000         -** when the connection currently holding the required lock relinquishes it.
  4001         -** ^This API is only available if the library was compiled with the
  4002         -** [SQLITE4_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined.
  4003         -**
  4004         -** See Also: [Using the SQLite Unlock Notification Feature].
  4005         -**
  4006         -** ^Shared-cache locks are released when a database connection concludes
  4007         -** its current transaction, either by committing it or rolling it back. 
  4008         -**
  4009         -** ^When a connection (known as the blocked connection) fails to obtain a
  4010         -** shared-cache lock and SQLITE4_LOCKED is returned to the caller, the
  4011         -** identity of the database connection (the blocking connection) that
  4012         -** has locked the required resource is stored internally. ^After an 
  4013         -** application receives an SQLITE4_LOCKED error, it may call the
  4014         -** sqlite4_unlock_notify() method with the blocked connection handle as 
  4015         -** the first argument to register for a callback that will be invoked
  4016         -** when the blocking connections current transaction is concluded. ^The
  4017         -** callback is invoked from within the [sqlite4_step] or [sqlite4_close]
  4018         -** call that concludes the blocking connections transaction.
  4019         -**
  4020         -** ^(If sqlite4_unlock_notify() is called in a multi-threaded application,
  4021         -** there is a chance that the blocking connection will have already
  4022         -** concluded its transaction by the time sqlite4_unlock_notify() is invoked.
  4023         -** If this happens, then the specified callback is invoked immediately,
  4024         -** from within the call to sqlite4_unlock_notify().)^
  4025         -**
  4026         -** ^If the blocked connection is attempting to obtain a write-lock on a
  4027         -** shared-cache table, and more than one other connection currently holds
  4028         -** a read-lock on the same table, then SQLite arbitrarily selects one of 
  4029         -** the other connections to use as the blocking connection.
  4030         -**
  4031         -** ^(There may be at most one unlock-notify callback registered by a 
  4032         -** blocked connection. If sqlite4_unlock_notify() is called when the
  4033         -** blocked connection already has a registered unlock-notify callback,
  4034         -** then the new callback replaces the old.)^ ^If sqlite4_unlock_notify() is
  4035         -** called with a NULL pointer as its second argument, then any existing
  4036         -** unlock-notify callback is canceled. ^The blocked connections 
  4037         -** unlock-notify callback may also be canceled by closing the blocked
  4038         -** connection using [sqlite4_close()].
  4039         -**
  4040         -** The unlock-notify callback is not reentrant. If an application invokes
  4041         -** any sqlite4_xxx API functions from within an unlock-notify callback, a
  4042         -** crash or deadlock may be the result.
  4043         -**
  4044         -** ^Unless deadlock is detected (see below), sqlite4_unlock_notify() always
  4045         -** returns SQLITE4_OK.
  4046         -**
  4047         -** <b>Callback Invocation Details</b>
  4048         -**
  4049         -** When an unlock-notify callback is registered, the application provides a 
  4050         -** single void* pointer that is passed to the callback when it is invoked.
  4051         -** However, the signature of the callback function allows SQLite to pass
  4052         -** it an array of void* context pointers. The first argument passed to
  4053         -** an unlock-notify callback is a pointer to an array of void* pointers,
  4054         -** and the second is the number of entries in the array.
  4055         -**
  4056         -** When a blocking connections transaction is concluded, there may be
  4057         -** more than one blocked connection that has registered for an unlock-notify
  4058         -** callback. ^If two or more such blocked connections have specified the
  4059         -** same callback function, then instead of invoking the callback function
  4060         -** multiple times, it is invoked once with the set of void* context pointers
  4061         -** specified by the blocked connections bundled together into an array.
  4062         -** This gives the application an opportunity to prioritize any actions 
  4063         -** related to the set of unblocked database connections.
  4064         -**
  4065         -** <b>Deadlock Detection</b>
  4066         -**
  4067         -** Assuming that after registering for an unlock-notify callback a 
  4068         -** database waits for the callback to be issued before taking any further
  4069         -** action (a reasonable assumption), then using this API may cause the
  4070         -** application to deadlock. For example, if connection X is waiting for
  4071         -** connection Y's transaction to be concluded, and similarly connection
  4072         -** Y is waiting on connection X's transaction, then neither connection
  4073         -** will proceed and the system may remain deadlocked indefinitely.
  4074         -**
  4075         -** To avoid this scenario, the sqlite4_unlock_notify() performs deadlock
  4076         -** detection. ^If a given call to sqlite4_unlock_notify() would put the
  4077         -** system in a deadlocked state, then SQLITE4_LOCKED is returned and no
  4078         -** unlock-notify callback is registered. The system is said to be in
  4079         -** a deadlocked state if connection A has registered for an unlock-notify
  4080         -** callback on the conclusion of connection B's transaction, and connection
  4081         -** B has itself registered for an unlock-notify callback when connection
  4082         -** A's transaction is concluded. ^Indirect deadlock is also detected, so
  4083         -** the system is also considered to be deadlocked if connection B has
  4084         -** registered for an unlock-notify callback on the conclusion of connection
  4085         -** C's transaction, where connection C is waiting on connection A. ^Any
  4086         -** number of levels of indirection are allowed.
  4087         -**
  4088         -** <b>The "DROP TABLE" Exception</b>
  4089         -**
  4090         -** When a call to [sqlite4_step()] returns SQLITE4_LOCKED, it is almost 
  4091         -** always appropriate to call sqlite4_unlock_notify(). There is however,
  4092         -** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement,
  4093         -** SQLite checks if there are any currently executing SELECT statements
  4094         -** that belong to the same connection. If there are, SQLITE4_LOCKED is
  4095         -** returned. In this case there is no "blocking connection", so invoking
  4096         -** sqlite4_unlock_notify() results in the unlock-notify callback being
  4097         -** invoked immediately. If the application then re-attempts the "DROP TABLE"
  4098         -** or "DROP INDEX" query, an infinite loop might be the result.
  4099         -**
  4100         -** One way around this problem is to check the extended error code returned
  4101         -** by an sqlite4_step() call. ^(If there is a blocking connection, then the
  4102         -** extended error code is set to SQLITE4_LOCKED_SHAREDCACHE. Otherwise, in
  4103         -** the special "DROP TABLE/INDEX" case, the extended error code is just 
  4104         -** SQLITE4_LOCKED.)^
  4105         -*/
  4106         -int sqlite4_unlock_notify(
  4107         -  sqlite4 *pBlocked,                          /* Waiting connection */
  4108         -  void (*xNotify)(void **apArg, int nArg),    /* Callback function to invoke */
  4109         -  void *pNotifyArg                            /* Argument to pass to xNotify */
  4110         -);
  4111         -
  4112   4037   
  4113   4038   /*
  4114   4039   ** CAPIREF: String Comparison
  4115   4040   **
  4116   4041   ** ^The [sqlite4_strnicmp()] API allows applications and extensions to
  4117   4042   ** compare the contents of two buffers containing UTF-8 strings in a
  4118   4043   ** case-independent fashion, using the same definition of case independence 
................................................................................
  4202   4127   #define SQLITE4_VTAB_CONSTRAINT_SUPPORT 1
  4203   4128   
  4204   4129   /*
  4205   4130   ** CAPIREF: Determine The Virtual Table Conflict Policy
  4206   4131   **
  4207   4132   ** This function may only be called from within a call to the [xUpdate] method
  4208   4133   ** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The
  4209         -** value returned is one of [SQLITE4_ROLLBACK], [SQLITE4_IGNORE], [SQLITE4_FAIL],
         4134  +** value returned is one of [SQLITE4_ROLLBACK], [SQLITE4_IGNORE],
         4135  +** [SQLITE4_FAIL],
  4210   4136   ** [SQLITE4_ABORT], or [SQLITE4_REPLACE], according to the [ON CONFLICT] mode
  4211   4137   ** of the SQL statement that triggered the call to the [xUpdate] method of the
  4212   4138   ** [virtual table].
  4213   4139   */
  4214   4140   int sqlite4_vtab_on_conflict(sqlite4 *);
  4215   4141   
  4216   4142   /*
................................................................................
  4323   4249   
  4324   4250   /*
  4325   4251   ** CAPIREF: Key-value storage object factory
  4326   4252   **
  4327   4253   ** New key/value storage engines can be added to SQLite4 at run-time.
  4328   4254   ** In order to create a new KV storage engine, the application must 
  4329   4255   ** supply a "factory" function that creates an instance of the
  4330         -** sqlite4_kvstore object.  This is typedef defines the signature
         4256  +** sqlite4_kvstore object.  This typedef defines the signature
  4331   4257   ** of that factory function.
  4332   4258   */
  4333   4259   typedef int (*sqlite4_kvfactory)(
  4334   4260     sqlite4_env *pEnv,             /* The environment to use */
  4335   4261     sqlite4_kvstore **ppKVStore,   /* OUT: New KV store returned here */
  4336   4262     const char *zFilename,         /* Name of database file to open */
  4337   4263     unsigned flags                 /* Bit flags */
................................................................................
  4343   4269   ** Every number in SQLite is represented in memory by an instance of
  4344   4270   ** the following object.
  4345   4271   */
  4346   4272   typedef struct sqlite4_num sqlite4_num;
  4347   4273   struct sqlite4_num {
  4348   4274     unsigned char sign;     /* Sign of the overall value */
  4349   4275     unsigned char approx;   /* True if the value is approximate */
  4350         -  unsigned short e;       /* The exponent. */
         4276  +  short e;                /* The exponent. */
  4351   4277     sqlite4_uint64 m;       /* The significant */
  4352   4278   };
  4353   4279   
  4354   4280   /*
  4355   4281   ** CAPI4REF: Operations On SQLite Number Objects
  4356   4282   */
  4357   4283   sqlite4_num sqlite4_num_add(sqlite4_num, sqlite4_num);

Changes to src/sqliteInt.h.

   164    164   **
   165    165   ** (Historical note:  There used to be several other options, but we've
   166    166   ** pared it down to just these three.)
   167    167   **
   168    168   ** If none of the above are defined, then set SQLITE4_SYSTEM_MALLOC as
   169    169   ** the default.
   170    170   */
   171         -#if defined(SQLITE4_SYSTEM_MALLOC)+defined(SQLITE4_WIN32_MALLOC)+defined(SQLITE4_MEMDEBUG)>1
          171  +#if defined(SQLITE4_SYSTEM_MALLOC)+defined(SQLITE4_WIN32_MALLOC)\
          172  +   +defined(SQLITE4_MEMDEBUG)>1
   172    173   # error "At most one of the following compile-time configuration options\
   173    174    is allows: SQLITE4_SYSTEM_MALLOC, SQLITE4_WIN32_MALLOC, SQLITE4_MEMDEBUG"
   174    175   #endif
   175         -#if defined(SQLITE4_SYSTEM_MALLOC)+defined(SQLITE4_WIN32_MALLOC)+defined(SQLITE4_MEMDEBUG)==0
          176  +#if defined(SQLITE4_SYSTEM_MALLOC)+defined(SQLITE4_WIN32_MALLOC)\
          177  +   +defined(SQLITE4_MEMDEBUG)==0
   176    178   # define SQLITE4_SYSTEM_MALLOC 1
   177    179   #endif
   178    180   
   179    181   /*
   180    182   ** If SQLITE4_MALLOC_SOFT_LIMIT is not zero, then try to keep the
   181    183   ** sizes of memory allocations below this value where possible.
   182    184   */
................................................................................
   193    195   ** Later we learn that _XOPEN_SOURCE is poorly or incorrectly
   194    196   ** implemented on some systems.  So we avoid defining it at all
   195    197   ** if it is already defined or if it is unneeded because we are
   196    198   ** not doing a threadsafe build.  Ticket #2681.
   197    199   **
   198    200   ** See also ticket #2741.
   199    201   */
   200         -#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) && SQLITE4_THREADSAFE
          202  +#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__)\
          203  +     && SQLITE4_THREADSAFE
   201    204   #  define _XOPEN_SOURCE 500  /* Needed to enable pthread recursive mutexes */
   202    205   #endif
   203    206   
   204    207   /*
   205    208   ** The TCL headers are only needed when compiling the TCL bindings.
   206    209   */
   207    210   #if defined(SQLITE4_TCL) || defined(TCLSH)
................................................................................
   460    463   /*
   461    464   ** Constants for the largest and smallest possible 64-bit signed integers.
   462    465   ** These macros are designed to work correctly on both 32-bit and 64-bit
   463    466   ** compilers.
   464    467   */
   465    468   #define LARGEST_INT64  (0xffffffff|(((i64)0x7fffffff)<<32))
   466    469   #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
   467         -#define LARGEST_UINT64  (0xffffffff|(((i64)0xffffffff)<<32))
          470  +#define LARGEST_UINT64  (0xffffffff|(((u64)0xffffffff)<<32))
   468    471   
   469    472   /* 
   470    473   ** Round up a number to the next larger multiple of 8.  This is used
   471    474   ** to force 8-byte alignment on 64-bit architectures.
   472    475   */
   473    476   #define ROUND8(x)     (((x)+7)&~7)
   474    477   
................................................................................
   760    763     u8 orphanTrigger;           /* Last statement is orphaned TEMP trigger */
   761    764   };
   762    765   
   763    766   
   764    767   /*
   765    768   ** Each database connection is an instance of the following structure.
   766    769   **
   767         -** The sqlite.lastRowid records the last insert rowid generated by an
   768         -** insert statement.  Inserts on views do not affect its value.  Each
   769         -** trigger has its own context, so that lastRowid can be updated inside
   770         -** triggers as usual.  The previous value will be restored once the trigger
   771         -** exits.  Upon entering a before or instead of trigger, lastRowid is no
   772         -** longer (since after version 2.8.12) reset to -1.
   773         -**
   774    770   ** The sqlite.nChange does not count changes within triggers and keeps no
   775    771   ** context.  It is reset at start of sqlite4_exec.
   776    772   ** The sqlite.lsChange represents the number of changes made by the last
   777    773   ** insert, update, or delete statement.  It remains constant throughout the
   778    774   ** length of a statement and is then updated by OP_SetCounts.  It keeps a
   779         -** context stack just like lastRowid so that the count of changes
          775  +** context stack so that the count of changes
   780    776   ** within a trigger is not seen outside the trigger.  Changes to views do not
   781    777   ** affect the value of lsChange.
   782    778   ** The sqlite.csChange keeps track of the number of current changes (since
   783    779   ** the last statement) and is used to update sqlite_lsChange.
   784    780   **
   785    781   ** The member variables sqlite.errCode, sqlite.zErrMsg and sqlite.zErrMsg16
   786    782   ** store the most recent error code and, if applicable, string. The
................................................................................
   799    795     u8 dfltLockMode;              /* Default locking-mode for attached dbs */
   800    796     signed char nextAutovac;      /* Autovac setting after VACUUM if >=0 */
   801    797     u8 suppressErr;               /* Do not issue error messages if true */
   802    798     u8 vtabOnConflict;            /* Value to return for s3_vtab_on_conflict() */
   803    799     int nextPagesize;             /* Pagesize after VACUUM if >0 */
   804    800     int nTable;                   /* Number of tables in the database */
   805    801     CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
   806         -  i64 lastRowid;                /* ROWID of most recent insert (see above) */
   807    802     u32 magic;                    /* Magic number for detect library misuse */
   808    803     int nChange;                  /* Value returned by sqlite4_changes() */
   809    804     int nTotalChange;             /* Value returned by sqlite4_total_changes() */
   810    805     sqlite4_mutex *mutex;         /* Connection mutex */
   811    806     int aLimit[SQLITE4_N_LIMIT];   /* Limits */
   812    807     Sqlite4InitInfo init;         /* Information used during initialization */
   813    808     int nExtension;               /* Number of loaded extensions */
................................................................................
   889    884   */
   890    885   #define ENC(db) ((db)->aDb[0].pSchema->enc)
   891    886   
   892    887   /*
   893    888   ** Possible values for the sqlite4.flags.
   894    889   */
   895    890   #define SQLITE4_VdbeTrace      0x00000100  /* True to trace VDBE execution */
   896         -#define SQLITE4_InternChanges  0x00000200  /* Uncommitted Hash table changes */
   897         -#define SQLITE4_CountRows      0x00001000  /* Count rows changed by INSERT, */
   898         -                                          /*   DELETE, or UPDATE and return */
   899         -                                          /*   the count using a callback. */
   900         -#define SQLITE4_SqlTrace       0x00004000  /* Debug print SQL as it executes */
   901         -#define SQLITE4_VdbeListing    0x00008000  /* Debug listings of VDBE programs */
   902         -#define SQLITE4_WriteSchema    0x00010000  /* OK to update SQLITE4_MASTER */
   903         -#define SQLITE4_KvTrace        0x00020000  /* Trace Key/value storage calls */
   904         -#define SQLITE4_IgnoreChecks   0x00040000  /* Do not enforce check constraints */
   905         -#define SQLITE4_ReadUncommitted 0x0080000  /* For shared-cache mode */
   906         -#define SQLITE4_LegacyFileFmt  0x00100000  /* Create new databases in format 1 */
   907         -#define SQLITE4_RecoveryMode   0x00800000  /* Ignore schema errors */
          891  +#define SQLITE4_SqlTrace       0x00000200  /* Debug print SQL as it executes */
          892  +#define SQLITE4_VdbeListing    0x00000400  /* Debug listings of VDBE programs */
          893  +#define SQLITE4_KvTrace        0x00000800  /* Trace Key/value storage calls */
          894  +#define SQLITE4_VdbeAddopTrace 0x00001000  /* Trace sqlite4VdbeAddOp() calls */
          895  +#define SQLITE4_InternChanges  0x00010000  /* Uncommitted Hash table changes */
          896  +#define SQLITE4_WriteSchema    0x00020000  /* OK to update SQLITE4_MASTER */
          897  +#define SQLITE4_IgnoreChecks   0x00040000  /* Dont enforce check constraints */
          898  +#define SQLITE4_RecoveryMode   0x00080000  /* Ignore schema errors */
   908    899   #define SQLITE4_ReverseOrder   0x01000000  /* Reverse unordered SELECTs */
   909    900   #define SQLITE4_RecTriggers    0x02000000  /* Enable recursive triggers */
   910         -#define SQLITE4_ForeignKeys    0x04000000  /* Enforce foreign key constraints  */
          901  +#define SQLITE4_ForeignKeys    0x04000000  /* Enable foreign key constraints */
   911    902   #define SQLITE4_AutoIndex      0x08000000  /* Enable automatic indexes */
   912    903   #define SQLITE4_PreferBuiltin  0x10000000  /* Preference to built-in funcs */
   913    904   #define SQLITE4_EnableTrigger  0x40000000  /* True to enable triggers */
   914    905   
   915    906   /*
   916    907   ** Bits of the sqlite4.flags field that are used by the
   917    908   ** sqlite4_test_control(SQLITE4_TESTCTRL_OPTIMIZATIONS,...) interface.
   918    909   ** These must be the low-order bits of the flags field.
   919    910   */
   920         -#define SQLITE4_QueryFlattener 0x01        /* Disable query flattening */
   921         -#define SQLITE4_ColumnCache    0x02        /* Disable the column cache */
   922         -#define SQLITE4_IndexSort      0x04        /* Disable indexes for sorting */
   923         -#define SQLITE4_IndexSearch    0x08        /* Disable indexes for searching */
   924         -#define SQLITE4_IndexCover     0x10        /* Disable index covering table */
   925         -#define SQLITE4_GroupByOrder   0x20        /* Disable GROUPBY cover of ORDERBY */
   926         -#define SQLITE4_FactorOutConst 0x40        /* Disable factoring out constants */
   927         -#define SQLITE4_IdxRealAsInt   0x80        /* Store REAL as INT in indices */
   928         -#define SQLITE4_DistinctOpt    0x80        /* DISTINCT using indexes */
   929         -#define SQLITE4_OptMask        0xff        /* Mask of all disablable opts */
          911  +#define SQLITE4_QueryFlattener 0x01     /* Disable query flattening */
          912  +#define SQLITE4_ColumnCache    0x02     /* Disable the column cache */
          913  +#define SQLITE4_IndexSort      0x04     /* Disable indexes for sorting */
          914  +#define SQLITE4_IndexSearch    0x08     /* Disable indexes for searching */
          915  +#define SQLITE4_IndexCover     0x10     /* Disable index covering table */
          916  +#define SQLITE4_GroupByOrder   0x20     /* Disable GROUPBY cover of ORDERBY */
          917  +#define SQLITE4_FactorOutConst 0x40     /* Disable factoring out constants */
          918  +#define SQLITE4_IdxRealAsInt   0x80     /* Store REAL as INT in indices */
          919  +#define SQLITE4_DistinctOpt    0x80     /* DISTINCT using indexes */
          920  +#define SQLITE4_OptMask        0xff     /* Mask of all disablable opts */
   930    921   
   931    922   /*
   932    923   ** Possible values for the sqlite.magic field.
   933    924   ** The numbers are obtained at random and have no special meaning, other
   934    925   ** than being distinct from one another.
   935    926   */
   936         -#define SQLITE4_MAGIC_OPEN     0xa029a697  /* Database is open */
   937         -#define SQLITE4_MAGIC_CLOSED   0x9f3c2d33  /* Database is closed */
   938         -#define SQLITE4_MAGIC_SICK     0x4b771290  /* Error and awaiting close */
   939         -#define SQLITE4_MAGIC_BUSY     0xf03b7906  /* Database currently in use */
   940         -#define SQLITE4_MAGIC_ERROR    0xb5357930  /* An SQLITE4_MISUSE error occurred */
          927  +#define SQLITE4_MAGIC_OPEN    0x4d06c919  /* Database is open */
          928  +#define SQLITE4_MAGIC_CLOSED  0x5f2246b4  /* Database is closed */
          929  +#define SQLITE4_MAGIC_SICK    0xcaad9e61  /* Error and awaiting close */
          930  +#define SQLITE4_MAGIC_BUSY    0xb07f8c8c  /* Database currently in use */
          931  +#define SQLITE4_MAGIC_ERROR   0x912e4c46  /* An SQLITE4_MISUSE error occurred */
   941    932   
   942    933   /*
   943    934   ** This structure encapsulates a user-function destructor callback (as
   944    935   ** configured using create_function_v2()) and a reference counter. When
   945    936   ** create_function_v2() is called to create a function with a destructor,
   946    937   ** a single object of this type is allocated. FuncDestructor.nRef is set to 
   947    938   ** the number of FuncDef objects created (either 1 or 3, depending on whether
................................................................................
   964    955   */
   965    956   #define SQLITE4_FUNC_LIKE     0x01 /* Candidate for the LIKE optimization */
   966    957   #define SQLITE4_FUNC_CASE     0x02 /* Case-sensitive LIKE-type function */
   967    958   #define SQLITE4_FUNC_EPHEM    0x04 /* Ephemeral.  Delete with VDBE */
   968    959   #define SQLITE4_FUNC_NEEDCOLL 0x08 /* sqlite4GetFuncCollSeq() might be called */
   969    960   #define SQLITE4_FUNC_PRIVATE  0x10 /* Allowed for internal use only */
   970    961   #define SQLITE4_FUNC_COUNT    0x20 /* Built-in count(*) aggregate */
   971         -#define SQLITE4_FUNC_COALESCE 0x40 /* Built-in coalesce() or ifnull() function */
          962  +#define SQLITE4_FUNC_COALESCE 0x40 /* Built-in coalesce() or ifnull() func */
   972    963   
   973    964   /*
   974    965   ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
   975    966   ** used to create the initializers for the FuncDef structures.
   976    967   **
   977    968   **   FUNCTION(zName, nArg, iArg, bNC, xFunc)
   978    969   **     Used to create a scalar function definition of a function zName 
................................................................................
  1122   1113   */
  1123   1114   #define SQLITE4_AFF_MASK     0x67
  1124   1115   
  1125   1116   /*
  1126   1117   ** Additional bit values that can be ORed with an affinity without
  1127   1118   ** changing the affinity.
  1128   1119   */
  1129         -#define SQLITE4_JUMPIFNULL   0x08  /* jumps if either operand is NULL */
  1130         -#define SQLITE4_STOREP2      0x10  /* Store result in reg[P2] rather than jump */
  1131         -#define SQLITE4_NULLEQ       0x80  /* NULL=NULL */
         1120  +#define SQLITE4_JUMPIFNULL  0x08  /* jumps if either operand is NULL */
         1121  +#define SQLITE4_STOREP2     0x10  /* Store result in reg[P2] rather than jump */
         1122  +#define SQLITE4_NULLEQ      0x80  /* NULL=NULL */
  1132   1123   
  1133   1124   /*
  1134   1125   ** An object of this type is created for each virtual table present in
  1135   1126   ** the database schema. 
  1136   1127   **
  1137   1128   ** If the database schema is shared, then there is one instance of this
  1138   1129   ** structure for each database connection (sqlite4*) that uses the shared
................................................................................
  1652   1643   */
  1653   1644   #define EP_FromJoin   0x0001  /* Originated in ON or USING clause of a join */
  1654   1645   #define EP_Agg        0x0002  /* Contains one or more aggregate functions */
  1655   1646   #define EP_Resolved   0x0004  /* IDs have been resolved to COLUMNs */
  1656   1647   #define EP_Error      0x0008  /* Expression contains one or more errors */
  1657   1648   #define EP_Distinct   0x0010  /* Aggregate function with DISTINCT keyword */
  1658   1649   #define EP_VarSelect  0x0020  /* pSelect is correlated, not constant */
  1659         -#define EP_DblQuoted  0x0040  /* token.z was originally in "..." */
  1660   1650   #define EP_InfixFunc  0x0080  /* True for an infix function: LIKE, GLOB, etc */
  1661   1651   #define EP_ExpCollate 0x0100  /* Collating sequence specified explicitly */
  1662   1652   #define EP_FixedDest  0x0200  /* Result needed in a specific register */
  1663   1653   #define EP_IntValue   0x0400  /* Integer value contained in u.iValue */
  1664   1654   #define EP_xIsSelect  0x0800  /* x.pSelect is valid (otherwise x.pList is) */
  1665   1655   #define EP_Hint       0x1000  /* Optimizer hint. Not required for correctness */
  1666   1656   #define EP_Reduced    0x2000  /* Expr struct is EXPR_REDUCEDSIZE bytes only */
................................................................................
  2184   2174     int nOnce;           /* Number of OP_Once instructions so far */
  2185   2175     int ckBase;          /* Base register of data during check constraints */
  2186   2176     int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
  2187   2177     int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
  2188   2178     int iNewidxReg;      /* First argument to OP_NewIdxid */
  2189   2179     u8 nColCache;        /* Number of entries in aColCache[] */
  2190   2180     u8 iColCache;        /* Next entry in aColCache[] to replace */
  2191         -  ParseYColCache aColCache[SQLITE4_N_COLCACHE]; /* One for each column cache entry */
         2181  +  ParseYColCache aColCache[SQLITE4_N_COLCACHE]; /* One per colcache entry */
  2192   2182     yDbMask writeMask;   /* Start a write transaction on these databases */
  2193   2183     yDbMask cookieMask;  /* Bitmask of schema verified databases */
  2194   2184     u8 isMultiWrite;     /* True if statement may affect/insert multiple rows */
  2195   2185     u8 mayAbort;         /* True if statement may throw an ABORT exception */
  2196   2186     int cookieGoto;      /* Address of OP_Goto to cookie verifier subroutine */
  2197   2187     int cookieValue[SQLITE4_MAX_ATTACHED+2];  /* Values of cookies to verify */
  2198   2188     int regRowid;        /* Register holding rowid of CREATE TABLE entry */
................................................................................
  2256   2246     Parse *pParse;              /* The Parse structure */
  2257   2247   };
  2258   2248   
  2259   2249   /*
  2260   2250   ** Bitfield flags for P5 value in OP_Insert and OP_Delete
  2261   2251   */
  2262   2252   #define OPFLAG_NCHANGE       0x01    /* Set to update db->nChange */
  2263         -#define OPFLAG_LASTROWID     0x02    /* Set to update db->lastRowid */
         2253  +#define OPFLAG_PARTIALKEY    0x02    /* Not all values given to OP_MakeIdxKey */
  2264   2254   #define OPFLAG_ISUPDATE      0x04    /* This OP_Insert is an sql UPDATE */
  2265   2255   #define OPFLAG_APPEND        0x08    /* This is likely to be an append */
  2266   2256   #define OPFLAG_SEQCOUNT      0x10    /* Append sequence number to key */
  2267   2257   #define OPFLAG_CLEARCACHE    0x20    /* Clear pseudo-table cache in OP_Column */
  2268   2258   #define OPFLAG_APPENDBIAS    0x40    /* Bias inserts for appending */
  2269   2259   
  2270   2260   /*
................................................................................
  2416   2406     int iVersion;                     /* Version number of this structure */
  2417   2407     int bMemstat;                     /* True to enable memory status */
  2418   2408     int bCoreMutex;                   /* True to enable core mutexing */
  2419   2409     int bFullMutex;                   /* True to enable full mutexing */
  2420   2410     int mxStrlen;                     /* Maximum string length */
  2421   2411     int szLookaside;                  /* Default lookaside buffer size */
  2422   2412     int nLookaside;                   /* Default lookaside buffer count */
         2413  +  sqlite4_mm *pMM;                  /* Memory allocator for this environment */
  2423   2414     sqlite4_mem_methods m;            /* Low-level memory allocation interface */
  2424   2415     sqlite4_mutex_methods mutex;      /* Low-level mutex interface */
  2425   2416     void *pHeap;                      /* Heap storage space */
  2426   2417     int nHeap;                        /* Size of pHeap[] */
  2427   2418     int mnReq, mxReq;                 /* Min and max heap requests sizes */
  2428   2419     int mxParserStack;                /* maximum depth of the parser stack */
  2429   2420     KVFactory *pFactory;              /* List of factories */
................................................................................
  2491   2482   */
  2492   2483   #define SQLITE4_SKIP_UTF8(zIn) {                        \
  2493   2484     if( (*(zIn++))>=0xc0 ){                              \
  2494   2485       while( (*zIn & 0xc0)==0x80 ){ zIn++; }             \
  2495   2486     }                                                    \
  2496   2487   }
  2497   2488   
         2489  +/*
         2490  +** Default memory allocator
         2491  +*/
         2492  +extern sqlite4_mm sqlite4MMSystem;
         2493  +
  2498   2494   /*
  2499   2495   ** The SQLITE4_*_BKPT macros are substitutes for the error codes with
  2500   2496   ** the same name but without the _BKPT suffix.  These macros invoke
  2501   2497   ** routines that report the line-number on which the error originated
  2502   2498   ** using sqlite4_log().  The routines also provide a convenient place
  2503   2499   ** to set a debugger breakpoint.
  2504   2500   */
................................................................................
  2742   2738   int sqlite4Select(Parse*, Select*, SelectDest*);
  2743   2739   Select *sqlite4SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
  2744   2740                            Expr*,ExprList*,int,Expr*,Expr*);
  2745   2741   void sqlite4SelectDelete(sqlite4*, Select*);
  2746   2742   Table *sqlite4SrcListLookup(Parse*, SrcList*);
  2747   2743   int sqlite4IsReadOnly(Parse*, Table*, int);
  2748   2744   void sqlite4OpenTable(Parse*, int iCur, int iDb, Table*, int);
  2749         -#if defined(SQLITE4_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE4_OMIT_SUBQUERY)
  2750         -Expr *sqlite4LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *, char *);
         2745  +#if defined(SQLITE4_ENABLE_UPDATE_DELETE_LIMIT) \
         2746  +    && !defined(SQLITE4_OMIT_SUBQUERY)
         2747  +Expr *sqlite4LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*);
  2751   2748   #endif
  2752   2749   void sqlite4DeleteFrom(Parse*, SrcList*, Expr*);
  2753   2750   void sqlite4Update(Parse*, SrcList*, ExprList*, Expr*, int);
  2754   2751   WhereInfo *sqlite4WhereBegin(Parse*, SrcList*, Expr*, ExprList**,ExprList*,u16);
  2755   2752   void sqlite4WhereEnd(WhereInfo*);
  2756   2753   int sqlite4ExprCodeGetColumn(Parse*, Table*, int, int, int);
  2757   2754   void sqlite4ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
................................................................................
  2923   2920   **     x = sqlite4GetVarint32( A, &B );
  2924   2921   **     x = sqlite4PutVarint32( A, B );
  2925   2922   **
  2926   2923   **     x = getVarint32( A, B );
  2927   2924   **     x = putVarint32( A, B );
  2928   2925   **
  2929   2926   */
  2930         -#define getVarint32(A,B)  (u8)((*(A)<(u8)0x80) ? ((B) = (u32)*(A)),1 : sqlite4GetVarint32((A), (u32 *)&(B)))
  2931         -#define putVarint32(A,B)  (u8)(((u32)(B)<(u32)0x80) ? (*(A) = (unsigned char)(B)),1 : sqlite4PutVarint32((A), (B)))
         2927  +#define getVarint32(A,B)  \
         2928  +  (u8)((*(A)<(u8)0x80)?((B)=(u32)*(A)),1:sqlite4GetVarint32((A),(u32 *)&(B)))
         2929  +#define putVarint32(A,B)  \
         2930  +  (u8)(((u32)(B)<(u32)0x80)?(*(A)=(unsigned char)(B)),1\
         2931  +  :sqlite4PutVarint32((A),(B)))
  2932   2932   #define getVarint    sqlite4GetVarint
  2933   2933   #define putVarint    sqlite4PutVarint
  2934   2934   
  2935   2935   
  2936   2936   const char *sqlite4IndexAffinityStr(Vdbe *, Index *);
  2937   2937   void sqlite4TableAffinityStr(Vdbe *, Table *);
  2938   2938   char sqlite4CompareAffinity(Expr *pExpr, char aff2);
................................................................................
  2963   2963   # define sqlite4FileSuffix3(X,Y)
  2964   2964   #endif
  2965   2965   u8 sqlite4GetBoolean(const char *z);
  2966   2966   
  2967   2967   const void *sqlite4ValueText(sqlite4_value*, u8);
  2968   2968   int sqlite4ValueBytes(sqlite4_value*, u8);
  2969   2969   void sqlite4ValueSetStr(sqlite4_value*, int, const void *,u8, 
  2970         -                        void(*)(void*));
         2970  +                        void(*)(void*,void*),void*);
  2971   2971   void sqlite4ValueFree(sqlite4_value*);
  2972   2972   sqlite4_value *sqlite4ValueNew(sqlite4 *);
  2973   2973   char *sqlite4Utf16to8(sqlite4 *, const void*, int, u8);
  2974   2974   #ifdef SQLITE4_ENABLE_STAT3
  2975   2975   char *sqlite4Utf8to16(sqlite4 *, u8, char *, int, int *);
  2976   2976   #endif
  2977   2977   int sqlite4ValueFromExpr(sqlite4 *, Expr *, u8, u8, sqlite4_value **);

Changes to src/tclsqlite.c.

   114    114     char *zTrace;              /* The trace callback routine */
   115    115     char *zProfile;            /* The profile callback routine */
   116    116     char *zProgress;           /* The progress callback routine */
   117    117     char *zAuth;               /* The authorization callback routine */
   118    118     int disableAuth;           /* Disable the authorizer if it exists */
   119    119     char *zNull;               /* Text to substitute for an SQL NULL value */
   120    120     SqlFunc *pFunc;            /* List of SQL functions */
   121         -  Tcl_Obj *pUnlockNotify;    /* Unlock notify script (if any) */
   122    121     SqlCollate *pCollate;      /* List of SQL collation functions */
   123    122     int rc;                    /* Return code of most recent sqlite4_exec() */
   124    123     Tcl_Obj *pCollateNeeded;   /* Collation needed script */
   125    124     SqlPreparedStmt *stmtList; /* List of prepared statements*/
   126    125     SqlPreparedStmt *stmtLast; /* Last statement in the list */
   127    126     int maxStmt;               /* The next maximum number of stmtList */
   128    127     int nStmt;                 /* Number of statements in stmtList */
................................................................................
   312    311     Tcl_DStringAppendElement(&str, zTm);
   313    312     Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
   314    313     Tcl_DStringFree(&str);
   315    314     Tcl_ResetResult(pDb->interp);
   316    315   }
   317    316   #endif
   318    317   
   319         -#if defined(SQLITE4_TEST) && defined(SQLITE4_ENABLE_UNLOCK_NOTIFY)
   320         -static void setTestUnlockNotifyVars(Tcl_Interp *interp, int iArg, int nArg){
   321         -  char zBuf[64];
   322         -  sprintf(zBuf, "%d", iArg);
   323         -  Tcl_SetVar(interp, "sqlite_unlock_notify_arg", zBuf, TCL_GLOBAL_ONLY);
   324         -  sprintf(zBuf, "%d", nArg);
   325         -  Tcl_SetVar(interp, "sqlite_unlock_notify_argcount", zBuf, TCL_GLOBAL_ONLY);
   326         -}
   327         -#else
   328         -# define setTestUnlockNotifyVars(x,y,z)
   329         -#endif
   330         -
   331         -#ifdef SQLITE4_ENABLE_UNLOCK_NOTIFY
   332         -static void DbUnlockNotify(void **apArg, int nArg){
   333         -  int i;
   334         -  for(i=0; i<nArg; i++){
   335         -    const int flags = (TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT);
   336         -    SqliteDb *pDb = (SqliteDb *)apArg[i];
   337         -    setTestUnlockNotifyVars(pDb->interp, i, nArg);
   338         -    assert( pDb->pUnlockNotify);
   339         -    Tcl_EvalObjEx(pDb->interp, pDb->pUnlockNotify, flags);
   340         -    Tcl_DecrRefCount(pDb->pUnlockNotify);
   341         -    pDb->pUnlockNotify = 0;
   342         -  }
   343         -}
   344         -#endif
   345         -
   346    318   static void tclCollateNeeded(
   347    319     void *pCtx,
   348    320     sqlite4 *db,
   349    321     int enc,
   350    322     const char *zName
   351    323   ){
   352    324     SqliteDb *pDb = (SqliteDb *)pCtx;
................................................................................
   502    474       u8 *data;
   503    475       const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
   504    476       char c = zType[0];
   505    477       if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){
   506    478         /* Only return a BLOB type if the Tcl variable is a bytearray and
   507    479         ** has no string representation. */
   508    480         data = Tcl_GetByteArrayFromObj(pVar, &n);
   509         -      sqlite4_result_blob(context, data, n, SQLITE4_TRANSIENT);
          481  +      sqlite4_result_blob(context, data, n, SQLITE4_TRANSIENT, 0);
   510    482       }else if( c=='b' && strcmp(zType,"boolean")==0 ){
   511    483         Tcl_GetIntFromObj(0, pVar, &n);
   512    484         sqlite4_result_int(context, n);
   513    485       }else if( c=='d' && strcmp(zType,"double")==0 ){
   514    486         double r;
   515    487         Tcl_GetDoubleFromObj(0, pVar, &r);
   516    488         sqlite4_result_double(context, r);
................................................................................
   517    489       }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
   518    490             (c=='i' && strcmp(zType,"int")==0) ){
   519    491         Tcl_WideInt v;
   520    492         Tcl_GetWideIntFromObj(0, pVar, &v);
   521    493         sqlite4_result_int64(context, v);
   522    494       }else{
   523    495         data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
   524         -      sqlite4_result_text(context, (char *)data, n, SQLITE4_TRANSIENT);
          496  +      sqlite4_result_text(context, (char *)data, n, SQLITE4_TRANSIENT, 0);
   525    497       }
   526    498     }
   527    499   }
   528    500   
   529    501   #ifndef SQLITE4_OMIT_AUTHORIZATION
   530    502   /*
   531    503   ** This is the authentication function.  It appends the authentication
................................................................................
   844    816           char c = zType[0];
   845    817           if( zVar[0]=='@' ||
   846    818              (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){
   847    819             /* Load a BLOB type if the Tcl variable is a bytearray and
   848    820             ** it has no string representation or the host
   849    821             ** parameter name begins with "@". */
   850    822             data = Tcl_GetByteArrayFromObj(pVar, &n);
   851         -          sqlite4_bind_blob(pStmt, i, data, n, SQLITE4_STATIC);
          823  +          sqlite4_bind_blob(pStmt, i, data, n, SQLITE4_STATIC, 0);
   852    824             Tcl_IncrRefCount(pVar);
   853    825             pPreStmt->apParm[iParm++] = pVar;
   854    826           }else if( c=='b' && strcmp(zType,"boolean")==0 ){
   855    827             Tcl_GetIntFromObj(interp, pVar, &n);
   856    828             sqlite4_bind_int(pStmt, i, n);
   857    829           }else if( c=='d' && strcmp(zType,"double")==0 ){
   858    830             double r;
................................................................................
   861    833           }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
   862    834                 (c=='i' && strcmp(zType,"int")==0) ){
   863    835             Tcl_WideInt v;
   864    836             Tcl_GetWideIntFromObj(interp, pVar, &v);
   865    837             sqlite4_bind_int64(pStmt, i, v);
   866    838           }else{
   867    839             data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
   868         -          sqlite4_bind_text(pStmt, i, (char *)data, n, SQLITE4_STATIC);
          840  +          sqlite4_bind_text(pStmt, i, (char *)data, n, SQLITE4_STATIC, 0);
   869    841             Tcl_IncrRefCount(pVar);
   870    842             pPreStmt->apParm[iParm++] = pVar;
   871    843           }
   872    844         }else{
   873    845           sqlite4_bind_null(pStmt, i);
   874    846         }
   875    847       }
................................................................................
  1269   1241     int choice;
  1270   1242     int rc = TCL_OK;
  1271   1243     static const char *DB_strs[] = {
  1272   1244       "authorizer",         "cache",             "changes",
  1273   1245       "close",              "collate",           "collation_needed",
  1274   1246       "complete",           "copy",              "enable_load_extension", 
  1275   1247       "errorcode",          "eval",              "exists",             
  1276         -    "function",           "interrupt",         "last_insert_rowid",
         1248  +    "function",           "interrupt",         
  1277   1249       "nullvalue",          "onecolumn",         "profile",
  1278   1250       "rekey",              "status",            "total_changes",
  1279         -    "trace",              "transaction",       "unlock_notify",
         1251  +    "trace",              "transaction",
  1280   1252       "version",            0
  1281   1253     };
  1282   1254     enum DB_enum {
  1283   1255       DB_AUTHORIZER,        DB_CACHE,            DB_CHANGES,
  1284   1256       DB_CLOSE,             DB_COLLATE,          DB_COLLATION_NEEDED,
  1285   1257       DB_COMPLETE,          DB_COPY,             DB_ENABLE_LOAD_EXTENSION, 
  1286   1258       DB_ERRORCODE,         DB_EVAL,             DB_EXISTS,            
  1287         -    DB_FUNCTION,          DB_INTERRUPT,        DB_LAST_INSERT_ROWID, 
         1259  +    DB_FUNCTION,          DB_INTERRUPT,        
  1288   1260       DB_NULLVALUE,         DB_ONECOLUMN,        DB_PROFILE,           
  1289   1261       DB_REKEY,             DB_STATUS,           DB_TOTAL_CHANGES,    
  1290         -    DB_TRACE,             DB_TRANSACTION,      DB_UNLOCK_NOTIFY,
         1262  +    DB_TRACE,             DB_TRANSACTION,
  1291   1263       DB_VERSION
  1292   1264     };
  1293   1265     /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
  1294   1266   
  1295   1267     if( objc<2 ){
  1296   1268       Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
  1297   1269       return TCL_ERROR;
................................................................................
  1666   1638         for(i=0; i<nCol; i++){
  1667   1639           /* check for null data, if so, bind as null */
  1668   1640           if( (nNull>0 && strcmp(azCol[i], zNull)==0)
  1669   1641             || strlen30(azCol[i])==0 
  1670   1642           ){
  1671   1643             sqlite4_bind_null(pStmt, i+1);
  1672   1644           }else{
  1673         -          sqlite4_bind_text(pStmt, i+1, azCol[i], -1, SQLITE4_STATIC);
         1645  +          sqlite4_bind_text(pStmt, i+1, azCol[i], -1, SQLITE4_STATIC, 0);
  1674   1646           }
  1675   1647         }
  1676   1648         sqlite4_step(pStmt);
  1677   1649         rc = sqlite4_reset(pStmt);
  1678   1650         free(zLine);
  1679   1651         if( rc!=SQLITE4_OK ){
  1680   1652           Tcl_AppendResult(interp,"Error: ", sqlite4_errmsg(pDb->db), 0);
................................................................................
  1899   1871           pDb->zNull = 0;
  1900   1872         }
  1901   1873       }
  1902   1874       Tcl_SetObjResult(interp, dbTextToObj(pDb->zNull));
  1903   1875       break;
  1904   1876     }
  1905   1877   
  1906         -  /*
  1907         -  **     $db last_insert_rowid 
  1908         -  **
  1909         -  ** Return an integer which is the ROWID for the most recent insert.
  1910         -  */
  1911         -  case DB_LAST_INSERT_ROWID: {
  1912         -    Tcl_Obj *pResult;
  1913         -    Tcl_WideInt rowid;
  1914         -    if( objc!=2 ){
  1915         -      Tcl_WrongNumArgs(interp, 2, objv, "");
  1916         -      return TCL_ERROR;
  1917         -    }
  1918         -    rowid = sqlite4_last_insert_rowid(pDb->db);
  1919         -    pResult = Tcl_GetObjResult(interp);
  1920         -    Tcl_SetWideIntObj(pResult, rowid);
  1921         -    break;
  1922         -  }
  1923         -
  1924   1878     /*
  1925   1879     ** The DB_ONECOLUMN method is implemented together with DB_EXISTS.
  1926   1880     */
  1927   1881   
  1928   1882   
  1929   1883     /*    $db profile ?CALLBACK?
  1930   1884     **
................................................................................
  2132   2086       ** or savepoint.  */
  2133   2087       if( DbUseNre() ){
  2134   2088         Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0);
  2135   2089         Tcl_NREvalObj(interp, pScript, 0);
  2136   2090       }else{
  2137   2091         rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0));
  2138   2092       }
  2139         -    break;
  2140         -  }
  2141         -
  2142         -  /*
  2143         -  **    $db unlock_notify ?script?
  2144         -  */
  2145         -  case DB_UNLOCK_NOTIFY: {
  2146         -#ifndef SQLITE4_ENABLE_UNLOCK_NOTIFY
  2147         -    Tcl_AppendResult(interp, "unlock_notify not available in this build", 0);
  2148         -    rc = TCL_ERROR;
  2149         -#else
  2150         -    if( objc!=2 && objc!=3 ){
  2151         -      Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
  2152         -      rc = TCL_ERROR;
  2153         -    }else{
  2154         -      void (*xNotify)(void **, int) = 0;
  2155         -      void *pNotifyArg = 0;
  2156         -
  2157         -      if( pDb->pUnlockNotify ){
  2158         -        Tcl_DecrRefCount(pDb->pUnlockNotify);
  2159         -        pDb->pUnlockNotify = 0;
  2160         -      }
  2161         -  
  2162         -      if( objc==3 ){
  2163         -        xNotify = DbUnlockNotify;
  2164         -        pNotifyArg = (void *)pDb;
  2165         -        pDb->pUnlockNotify = objv[2];
  2166         -        Tcl_IncrRefCount(pDb->pUnlockNotify);
  2167         -      }
  2168         -  
  2169         -      if( sqlite4_unlock_notify(pDb->db, xNotify, pNotifyArg) ){
  2170         -        Tcl_AppendResult(interp, sqlite4_errmsg(pDb->db), 0);
  2171         -        rc = TCL_ERROR;
  2172         -      }
  2173         -    }
  2174         -#endif
  2175   2093       break;
  2176   2094     }
  2177   2095   
  2178   2096     /*    $db version
  2179   2097     **
  2180   2098     ** Return the version string for this database.
  2181   2099     */
................................................................................
  2799   2717   static void md5finalize(sqlite4_context *context){
  2800   2718     MD5Context *p;
  2801   2719     unsigned char digest[16];
  2802   2720     char zBuf[33];
  2803   2721     p = sqlite4_aggregate_context(context, sizeof(*p));
  2804   2722     MD5Final(digest,p);
  2805   2723     MD5DigestToBase16(digest, zBuf);
  2806         -  sqlite4_result_text(context, zBuf, -1, SQLITE4_TRANSIENT);
         2724  +  sqlite4_result_text(context, zBuf, -1, SQLITE4_TRANSIENT, 0);
  2807   2725   }
  2808   2726   int Md5_Register(sqlite4 *db){
  2809   2727     int rc = sqlite4_create_function(db, "md5sum", -1, SQLITE4_UTF8, 0, 0, 
  2810   2728                                    md5step, md5finalize);
  2811   2729     sqlite4_overload_function(db, "md5sum", -1);  /* To exercise this API */
  2812   2730     return rc;
  2813   2731   }

Changes to src/tokenize.c.

   223    223         *tokenType = TK_BITAND;
   224    224         return 1;
   225    225       }
   226    226       case '~': {
   227    227         *tokenType = TK_BITNOT;
   228    228         return 1;
   229    229       }
   230         -    case '`':
   231    230       case '\'':
   232    231       case '"': {
   233    232         int delim = z[0];
   234    233         testcase( delim=='`' );
   235    234         testcase( delim=='\'' );
   236    235         testcase( delim=='"' );
   237    236         for(i=1; (c=z[i])!=0; i++){

Changes to src/utf.c.

   470    470   **
   471    471   ** NULL is returned if there is an allocation error.
   472    472   */
   473    473   char *sqlite4Utf16to8(sqlite4 *db, const void *z, int nByte, u8 enc){
   474    474     Mem m;
   475    475     memset(&m, 0, sizeof(m));
   476    476     m.db = db;
   477         -  sqlite4VdbeMemSetStr(&m, z, nByte, enc, SQLITE4_STATIC);
          477  +  sqlite4VdbeMemSetStr(&m, z, nByte, enc, SQLITE4_STATIC, 0);
   478    478     sqlite4VdbeChangeEncoding(&m, SQLITE4_UTF8);
   479    479     if( db->mallocFailed ){
   480    480       sqlite4VdbeMemRelease(&m);
   481    481       m.z = 0;
   482    482     }
   483    483     assert( (m.flags & MEM_Term)!=0 || db->mallocFailed );
   484    484     assert( (m.flags & MEM_Str)!=0 || db->mallocFailed );
................................................................................
   498    498   ** flag set.
   499    499   */
   500    500   #ifdef SQLITE4_ENABLE_STAT3
   501    501   char *sqlite4Utf8to16(sqlite4 *db, u8 enc, char *z, int n, int *pnOut){
   502    502     Mem m;
   503    503     memset(&m, 0, sizeof(m));
   504    504     m.db = db;
   505         -  sqlite4VdbeMemSetStr(&m, z, n, SQLITE4_UTF8, SQLITE4_STATIC);
          505  +  sqlite4VdbeMemSetStr(&m, z, n, SQLITE4_UTF8, SQLITE4_STATIC, 0);
   506    506     if( sqlite4VdbeMemTranslate(&m, enc) ){
   507    507       assert( db->mallocFailed );
   508    508       return 0;
   509    509     }
   510    510     assert( m.z==m.zMalloc );
   511    511     *pnOut = m.n;
   512    512     return m.z;

Changes to src/util.c.

   128    128       db->errCode = err_code;
   129    129       if( zFormat ){
   130    130         char *z;
   131    131         va_list ap;
   132    132         va_start(ap, zFormat);
   133    133         z = sqlite4VMPrintf(db, zFormat, ap);
   134    134         va_end(ap);
   135         -      sqlite4ValueSetStr(db->pErr, -1, z, SQLITE4_UTF8, SQLITE4_DYNAMIC);
          135  +      sqlite4ValueSetStr(db->pErr, -1, z, SQLITE4_UTF8, SQLITE4_DYNAMIC, 0);
   136    136       }else{
   137         -      sqlite4ValueSetStr(db->pErr, 0, 0, SQLITE4_UTF8, SQLITE4_STATIC);
          137  +      sqlite4ValueSetStr(db->pErr, 0, 0, SQLITE4_UTF8, SQLITE4_STATIC, 0);
   138    138       }
   139    139     }
   140    140   }
   141    141   
   142    142   /*
   143    143   ** Add an error message to pParse->zErrMsg and increment pParse->nErr.
   144    144   ** The following formatting characters are allowed:

Changes to src/vdbe.c.

   349    349       for(i=0; i<16 && i<pMem->n; i++){
   350    350         char z = pMem->z[i];
   351    351         if( z<32 || z>126 ) *zCsr++ = '.';
   352    352         else *zCsr++ = z;
   353    353       }
   354    354   
   355    355       zCsr += sqlite4_snprintf(zCsr, 100, "]%s", encnames[pMem->enc]);
   356         -    if( f & MEM_Zero ){
   357         -      zCsr += sqlite4_snprintf(zCsr, 100, "+%dz",pMem->u.nZero);
   358         -    }
   359    356       *zCsr = '\0';
   360    357     }else if( f & MEM_Str ){
   361    358       int j, k;
   362    359       zBuf[0] = ' ';
   363    360       if( f & MEM_Dyn ){
   364    361         zBuf[1] = 'z';
   365    362         assert( (f & (MEM_Static|MEM_Ephem))==0 );
................................................................................
   525    522     Mem *aMem = p->aMem;       /* Copy of p->aMem */
   526    523     Mem *pIn1 = 0;             /* 1st input operand */
   527    524     Mem *pIn2 = 0;             /* 2nd input operand */
   528    525     Mem *pIn3 = 0;             /* 3rd input operand */
   529    526     Mem *pOut = 0;             /* Output operand */
   530    527     int iCompare = 0;          /* Result of last OP_Compare operation */
   531    528     int *aPermute = 0;         /* Permutation of columns for OP_Compare */
   532         -  i64 lastRowid = db->lastRowid;  /* Saved value of the last insert ROWID */
   533    529   #ifdef VDBE_PROFILE
   534    530     u64 start;                 /* CPU clock count at start of opcode */
   535    531     int origPc;                /* Program counter at start of opcode */
   536    532   #endif
   537    533     /*** INSERT STACK UNION HERE ***/
   538    534   
   539    535     assert( p->magic==VDBE_MAGIC_RUN );  /* sqlite4_step() verifies this */
................................................................................
   794    790     if( pOp->p1==SQLITE4_OK && p->pFrame ){
   795    791       /* Halt the sub-program. Return control to the parent frame. */
   796    792       VdbeFrame *pFrame = p->pFrame;
   797    793       p->pFrame = pFrame->pParent;
   798    794       p->nFrame--;
   799    795       sqlite4VdbeSetChanges(db, p->nChange);
   800    796       pc = sqlite4VdbeFrameRestore(pFrame);
   801         -    lastRowid = db->lastRowid;
   802    797       if( pOp->p2==OE_Ignore ){
   803    798         /* Instruction pc is the OP_Program that invoked the sub-program 
   804    799         ** currently being halted. If the p2 instruction of this OP_Halt
   805    800         ** instruction is set to OE_Ignore, then the sub-program is throwing
   806    801         ** an IGNORE exception. In this case jump to the address specified
   807    802         ** as the p2 of the calling OP_Program.  */
   808    803         pc = p->aOp[pc].p2-1;
................................................................................
   880    875   case OP_String8: {         /* same as TK_STRING, out2-prerelease */
   881    876     assert( pOp->p4.z!=0 );
   882    877     pOp->opcode = OP_String;
   883    878     pOp->p1 = sqlite4Strlen30(pOp->p4.z);
   884    879   
   885    880   #ifndef SQLITE4_OMIT_UTF16
   886    881     if( encoding!=SQLITE4_UTF8 ){
   887         -    rc = sqlite4VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE4_UTF8, SQLITE4_STATIC);
          882  +    rc = sqlite4VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE4_UTF8,
          883  +                              SQLITE4_STATIC, 0);
   888    884       if( rc==SQLITE4_TOOBIG ) goto too_big;
   889    885       if( SQLITE4_OK!=sqlite4VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
   890    886       assert( pOut->zMalloc==pOut->z );
   891    887       assert( pOut->flags & MEM_Dyn );
   892    888       pOut->zMalloc = 0;
   893    889       pOut->flags |= MEM_Static;
   894    890       pOut->flags &= ~MEM_Dyn;
................................................................................
   946    942   /* Opcode: Blob P1 P2 * P4
   947    943   **
   948    944   ** P4 points to a blob of data P1 bytes long.  Store this
   949    945   ** blob in register P2.
   950    946   */
   951    947   case OP_Blob: {                /* out2-prerelease */
   952    948     assert( pOp->p1 <= SQLITE4_MAX_LENGTH );
   953         -  sqlite4VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
          949  +  sqlite4VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0, 0);
   954    950     pOut->enc = encoding;
   955    951     UPDATE_MAX_BLOBSIZE(pOut);
   956    952     break;
   957    953   }
   958    954   
   959    955   /* Opcode: Variable P1 P2 * P4 *
   960    956   **
................................................................................
  1141   1137     pIn2 = &aMem[pOp->p2];
  1142   1138     pOut = &aMem[pOp->p3];
  1143   1139     assert( pIn1!=pOut );
  1144   1140     if( (pIn1->flags | pIn2->flags) & MEM_Null ){
  1145   1141       sqlite4VdbeMemSetNull(pOut);
  1146   1142       break;
  1147   1143     }
  1148         -  if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
  1149   1144     Stringify(pIn1, encoding);
  1150   1145     Stringify(pIn2, encoding);
  1151   1146     nByte = pIn1->n + pIn2->n;
  1152   1147     if( nByte>db->aLimit[SQLITE4_LIMIT_LENGTH] ){
  1153   1148       goto too_big;
  1154   1149     }
  1155   1150     MemSetTypeFlag(pOut, MEM_Str);
................................................................................
  1382   1377     ctx.isError = 0;
  1383   1378     if( ctx.pFunc->flags & SQLITE4_FUNC_NEEDCOLL ){
  1384   1379       assert( pOp>aOp );
  1385   1380       assert( pOp[-1].p4type==P4_COLLSEQ );
  1386   1381       assert( pOp[-1].opcode==OP_CollSeq );
  1387   1382       ctx.pColl = pOp[-1].p4.pColl;
  1388   1383     }
  1389         -  db->lastRowid = lastRowid;
  1390   1384     (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
  1391         -  lastRowid = db->lastRowid;
  1392   1385   
  1393   1386     /* If any auxiliary data functions have been called by this user function,
  1394   1387     ** immediately call the destructor for any non-static values.
  1395   1388     */
  1396   1389     if( ctx.pVdbeFunc ){
  1397   1390       sqlite4VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p1);
  1398   1391       pOp->p4.pVdbeFunc = ctx.pVdbeFunc;
................................................................................
  1583   1576   case OP_ToText: {                  /* same as TK_TO_TEXT, in1 */
  1584   1577     pIn1 = &aMem[pOp->p1];
  1585   1578     memAboutToChange(p, pIn1);
  1586   1579     if( pIn1->flags & MEM_Null ) break;
  1587   1580     assert( MEM_Str==(MEM_Blob>>3) );
  1588   1581     pIn1->flags |= (pIn1->flags&MEM_Blob)>>3;
  1589   1582     applyAffinity(pIn1, SQLITE4_AFF_TEXT, encoding);
  1590         -  rc = ExpandBlob(pIn1);
  1591   1583     assert( pIn1->flags & MEM_Str || db->mallocFailed );
  1592         -  pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
         1584  +  pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob);
  1593   1585     UPDATE_MAX_BLOBSIZE(pIn1);
  1594   1586     break;
  1595   1587   }
  1596   1588   
  1597   1589   /* Opcode: ToBlob P1 * * * *
  1598   1590   **
  1599   1591   ** Force the value in register P1 to be a BLOB.
................................................................................
  2197   2189   ** the result to register P3. No affinity transformations are applied to 
  2198   2190   ** the input values before they are encoded. 
  2199   2191   **
  2200   2192   ** If the OPFLAG_SEQCOUNT bit of P5 is set, then a sequence number 
  2201   2193   ** (unique within the cursor) is appended to the record. The sole purpose
  2202   2194   ** of this is to ensure that the key blob is unique within the cursors table.
  2203   2195   **
  2204         -** If the OPFLAG_LASTROWID bit of P5 is set and the value of the first and
  2205         -** only field of the key is an integer, then set the lastRowid field to the
  2206         -** value of that integer.
         2196  +** If the OPFLAG_PARTIALKEY bit of P5 is set, that means the value supplied
         2197  +** for N is not the true number of values in the key, only the number that
         2198  +** need to be encoded for this operation.  This effects the encoding of
         2199  +** final BLOBs.
  2207   2200   */
  2208   2201   case OP_MakeIdxKey: {
  2209   2202     VdbeCursor *pC;
  2210   2203     KeyInfo *pKeyInfo;
  2211   2204     Mem *pData0;                    /* First in array of input registers */
  2212   2205     u8 *aRec;                       /* The constructed database key */
  2213   2206     int nRec;                       /* Size of aRec[] in bytes */
................................................................................
  2232   2225       do {
  2233   2226         nSeq++;
  2234   2227         aSeq[sizeof(aSeq)-nSeq] = (u8)(iSeq & 0x007F);
  2235   2228         iSeq = iSeq >> 7;
  2236   2229       }while( iSeq );
  2237   2230       aSeq[sizeof(aSeq)-nSeq] |= 0x80;
  2238   2231     }
  2239         -  if( (pOp->p5 & OPFLAG_LASTROWID)!=0 && (pData0->flags & MEM_Int)!=0 ){
  2240         -    lastRowid = pData0->u.i;
  2241         -  }
  2242   2232   
  2243   2233     memAboutToChange(p, pOut);
  2244   2234   
  2245   2235     nField = pKeyInfo->nField;
  2246   2236     if( pOp->p4type==P4_INT32 && pOp->p4.i ){
  2247   2237       nField = pOp->p4.i;
  2248   2238       assert( nField<=pKeyInfo->nField );
  2249   2239     }
  2250   2240     rc = sqlite4VdbeEncodeKey(
  2251         -    db, pData0, nField, pC->iRoot, pKeyInfo, &aRec, &nRec, nSeq
         2241  +    db, pData0, nField, nField+(pOp->p5 & OPFLAG_PARTIALKEY),
         2242  +    pC->iRoot, pKeyInfo, &aRec, &nRec, nSeq
  2252   2243     );
  2253   2244   
  2254   2245     if( rc ){
  2255   2246       sqlite4DbFree(db, aRec);
  2256   2247     }else{
  2257   2248       if( nSeq ){
  2258   2249         memcpy(&aRec[nRec], &aSeq[sizeof(aSeq)-nSeq], nSeq);
  2259   2250       }
  2260         -    rc = sqlite4VdbeMemSetStr(pOut, (char *)aRec, nRec+nSeq, 0, SQLITE4_DYNAMIC);
         2251  +    rc = sqlite4VdbeMemSetStr(pOut, (char *)aRec, nRec+nSeq, 0,
         2252  +                              SQLITE4_DYNAMIC, 0);
  2261   2253       REGISTER_TRACE(pOp->p3, pOut);
  2262   2254       UPDATE_MAX_BLOBSIZE(pOut);
  2263   2255     }
  2264   2256   
  2265   2257     break;
  2266   2258   }
  2267   2259   
................................................................................
  2329   2321     ** expand all zero-blobs.
  2330   2322     */
  2331   2323     for(pMem=pData0; pMem<=pLast; pMem++){
  2332   2324       assert( memIsValid(pMem) );
  2333   2325       if( zAffinity ){
  2334   2326         applyAffinity(pMem, *(zAffinity++), encoding);
  2335   2327       }
  2336         -    if( pMem->flags&MEM_Zero ){
  2337         -      (void)ExpandBlob(pMem);
  2338         -    }
  2339   2328     }
  2340   2329   
  2341   2330     /* Compute the key (if this is a MakeKey opcode) */
  2342   2331     if( pC ){
  2343   2332       aRec = 0;
  2344   2333       rc = sqlite4VdbeEncodeKey(db, 
  2345         -        pData0, pC->pKeyInfo->nField, pC->iRoot, pC->pKeyInfo, &aRec, &nRec, 0
         2334  +        pData0, pC->pKeyInfo->nField, pC->pKeyInfo->nField,
         2335  +        pC->iRoot, pC->pKeyInfo, &aRec, &nRec, 0
  2346   2336       );
  2347   2337       if( rc ){
  2348   2338         sqlite4DbFree(db, aRec);
  2349   2339       }else{
  2350         -      rc = sqlite4VdbeMemSetStr(pKeyOut, (char *)aRec, nRec, 0, SQLITE4_DYNAMIC);
         2340  +      rc = sqlite4VdbeMemSetStr(pKeyOut, (char *)aRec, nRec, 0,
         2341  +                                SQLITE4_DYNAMIC, 0);
  2351   2342         REGISTER_TRACE(keyReg, pKeyOut);
  2352   2343         UPDATE_MAX_BLOBSIZE(pKeyOut);
  2353   2344       }
  2354   2345     }
  2355   2346   
  2356   2347     /* If P3 is not 0, compute the data rescord */
  2357   2348     if( rc==SQLITE4_OK && pOp->p3 ){
................................................................................
  2359   2350       pOut = &aMem[pOp->p3];
  2360   2351       memAboutToChange(p, pOut);
  2361   2352       aRec = 0;
  2362   2353       rc = sqlite4VdbeEncodeData(db, pData0, nField, &aRec, &nRec);
  2363   2354       if( rc ){
  2364   2355         sqlite4DbFree(db, aRec);
  2365   2356       }else{
  2366         -      rc = sqlite4VdbeMemSetStr(pOut, (char *)aRec, nRec, 0, SQLITE4_DYNAMIC);
         2357  +      rc = sqlite4VdbeMemSetStr(pOut, (char *)aRec, nRec, 0, SQLITE4_DYNAMIC,0);
  2367   2358         REGISTER_TRACE(pOp->p3, pOut);
  2368   2359         UPDATE_MAX_BLOBSIZE(pOut);
  2369   2360       }
  2370   2361     }
  2371   2362     break;
  2372   2363   }
  2373   2364   
................................................................................
  2578   2569       p->expired = 0;
  2579   2570     }
  2580   2571     break;
  2581   2572   }
  2582   2573   
  2583   2574   /* Opcode: VerifyCookie P1 P2 P3 * *
  2584   2575   **
  2585         -** cHECK THe value of global database parameter number 0 (the
         2576  +** Check the value of global database parameter number 0 (the
  2586   2577   ** schema version) and make sure it is equal to P2 and that the
  2587   2578   ** generation counter on the local schema parse equals P3.
  2588   2579   **
  2589   2580   ** P1 is the database number which is 0 for the main database file
  2590   2581   ** and 1 for the file holding temporary tables and some higher number
  2591   2582   ** for auxiliary databases.
  2592   2583   **
................................................................................
  2996   2987     /* Encode a database key consisting of the contents of the P4 registers
  2997   2988     ** starting at register P3. Have the vdbecodec module allocate an extra
  2998   2989     ** free byte at the end of the database key (see below).  */
  2999   2990     op = pOp->opcode;
  3000   2991     nField = pOp->p4.i;
  3001   2992     pIn3 = &aMem[pOp->p3];
  3002   2993     rc = sqlite4VdbeEncodeKey(
  3003         -      db, pIn3, nField, pC->iRoot, pC->pKeyInfo, &aProbe, &nProbe, 1
         2994  +      db, pIn3, nField, nField+(pOp->p5 & OPFLAG_PARTIALKEY),
         2995  +      pC->iRoot, pC->pKeyInfo, &aProbe, &nProbe, 1
  3004   2996     );
  3005   2997   
  3006   2998     /*   Opcode    search-dir    increment-key
  3007   2999     **  --------------------------------------
  3008   3000     **   SeekLt    -1            no
  3009   3001     **   SeekLe    -1            yes
  3010   3002     **   SeekGe    +1            no
................................................................................
  3057   3049     KVSize nKey;
  3058   3050   
  3059   3051     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  3060   3052     pC = p->apCsr[pOp->p1];
  3061   3053     assert( pC!=0 );
  3062   3054     assert( pC->isTable );
  3063   3055     pKVCur = pC->pKVCur;
  3064         -  rc = sqlite4VdbeEncodeKey(db, aMem+pOp->p2, 1, pC->iRoot, 0,
         3056  +  rc = sqlite4VdbeEncodeKey(db, aMem+pOp->p2, 1, 1, pC->iRoot, 0,
  3065   3057                               &aKey, &nKey, 0);
  3066   3058     if( rc==SQLITE4_OK ){
  3067   3059       rc = sqlite4KVCursorSeek(pKVCur, aKey, nKey, 0);
  3068   3060       if( rc==SQLITE4_NOTFOUND ) rc = SQLITE4_CORRUPT_BKPT;
  3069   3061     }
  3070   3062     sqlite4DbFree(db, aKey);
  3071   3063     break;
................................................................................
  3134   3126     assert( pOp->p4type==P4_INT32 );
  3135   3127     pC = p->apCsr[pOp->p1];
  3136   3128     assert( pC!=0 );
  3137   3129     pIn3 = &aMem[pOp->p3];
  3138   3130     assert( pC->pKVCur!=0 );
  3139   3131     assert( pC->isTable==0 || pOp->opcode==OP_NotExists );
  3140   3132     if( pOp->p4.i>0 ){
  3141         -    rc = sqlite4VdbeEncodeKey(db, pIn3, pOp->p4.i, pC->iRoot,
  3142         -                              pC->pKeyInfo, &pProbe, &nProbe, 0);
         3133  +    rc = sqlite4VdbeEncodeKey(
         3134  +        db, pIn3, pOp->p4.i, pOp->p4.i + (pOp->p5 & OPFLAG_PARTIALKEY),
         3135  +        pC->iRoot, pC->pKeyInfo, &pProbe, &nProbe, 0
         3136  +    );
  3143   3137       pFree = pProbe;
  3144   3138     }else{
  3145   3139       pProbe = (KVByteArray*)pIn3->z;
  3146   3140       nProbe = pIn3->n;
  3147   3141       pFree = 0;
  3148   3142     }
  3149   3143     if( rc==SQLITE4_OK ){
................................................................................
  3434   3428       iKey = pKey->u.i;
  3435   3429     }else{
  3436   3430       /* assert( pOp->opcode==OP_InsertInt ); */
  3437   3431       iKey = pOp->p3;
  3438   3432     }
  3439   3433   
  3440   3434     if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  3441         -  if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = iKey;
  3442   3435     if( pData->flags & MEM_Null ){
  3443   3436       pData->z = 0;
  3444   3437       pData->n = 0;
  3445   3438     }else{
  3446   3439       assert( pData->flags & (MEM_Blob|MEM_Str) );
  3447   3440     }
  3448   3441     n = sqlite4PutVarint64(aKey, pC->iRoot);
................................................................................
  3517   3510   
  3518   3511     pIn3 = &aMem[pOp->p3];
  3519   3512     if( (pIn3->flags & MEM_Blob) 
  3520   3513      && pIn3->n==nKey && 0==memcmp(pIn3->z, aKey, nKey) 
  3521   3514     ){
  3522   3515       pc = pOp->p2-1;
  3523   3516     }else{
  3524         -    sqlite4VdbeMemSetStr(pIn3, (const char*)aKey, nKey, 0, SQLITE4_TRANSIENT);
         3517  +    sqlite4VdbeMemSetStr(pIn3, (const char*)aKey, nKey, 0, SQLITE4_TRANSIENT,0);
  3525   3518     }
  3526   3519   
  3527   3520     break;
  3528   3521   };
  3529   3522   
  3530   3523   /* Opcode: SorterData P1 P2 * * *
  3531   3524   **
  3532   3525   ** Write into register P2 the current sorter data for sorter cursor P1.
  3533   3526   */
  3534         -case OP_SorterData: {
  3535         -  VdbeCursor *pC; 
  3536         -  pOut = &aMem[pOp->p2];
  3537         -  pC = p->apCsr[pOp->p1];
  3538         -  assert( pC!=0 );
  3539         -  pOp->opcode = OP_RowData;
  3540         -  pc--;
  3541         -  break;
  3542         -}
  3543         -
  3544   3527   /* Opcode: RowData P1 P2 * * *
  3545   3528   **
  3546   3529   ** Write into register P2 the complete row data for cursor P1.
  3547   3530   ** There is no interpretation of the data.  
  3548   3531   ** It is just copied onto the P2 register exactly as 
  3549   3532   ** it is found in the database file.
  3550   3533   **
................................................................................
  3557   3540   ** There is no interpretation of the data.  
  3558   3541   ** The key is copied onto the P3 register exactly as 
  3559   3542   ** it is found in the database file.
  3560   3543   **
  3561   3544   ** If the P1 cursor must be pointing to a valid row (not a NULL row)
  3562   3545   ** of a real table, not a pseudo-table.
  3563   3546   */
         3547  +case OP_SorterData:
  3564   3548   case OP_RowKey:
  3565   3549   case OP_RowData: {
  3566   3550     VdbeCursor *pC;
  3567   3551     KVCursor *pCrsr;
  3568   3552     const KVByteArray *pData;
  3569   3553     KVSize nData;
  3570   3554   
................................................................................
  3584   3568       rc = sqlite4KVCursorKey(pCrsr, &pData, &nData);
  3585   3569     }else{
  3586   3570       rc = sqlite4KVCursorData(pCrsr, 0, -1, &pData, &nData);
  3587   3571     }
  3588   3572     if( rc==SQLITE4_OK && nData>db->aLimit[SQLITE4_LIMIT_LENGTH] ){
  3589   3573       goto too_big;
  3590   3574     }
  3591         -  sqlite4VdbeMemSetStr(pOut, (const char*)pData, nData, 0, SQLITE4_TRANSIENT);
         3575  +  sqlite4VdbeMemSetStr(pOut, (const char*)pData, nData, 0, SQLITE4_TRANSIENT,0);
  3592   3576     pOut->enc = SQLITE4_UTF8;  /* In case the blob is ever cast to text */
  3593   3577     UPDATE_MAX_BLOBSIZE(pOut);
  3594   3578     break;
  3595   3579   }
  3596   3580   
  3597   3581   /* Opcode: Rowid P1 P2 * * *
  3598   3582   **
................................................................................
  3646   3630   case OP_NullRow: {
  3647   3631     VdbeCursor *pC;
  3648   3632   
  3649   3633     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  3650   3634     pC = p->apCsr[pOp->p1];
  3651   3635     assert( pC!=0 );
  3652   3636     pC->nullRow = 1;
  3653         -  pC->rowidIsValid = 0;
  3654   3637     break;
  3655   3638   }
  3656   3639   
  3657   3640   /* Opcode: Last P1 P2 * * *
  3658   3641   **
  3659   3642   ** The next use of the Rowid or Column or Next instruction for P1 
  3660   3643   ** will refer to the last entry in the database table or index.
................................................................................
  3787   3770   #ifdef SQLITE4_TEST
  3788   3771       sqlite4_search_count++;
  3789   3772   #endif
  3790   3773     }else if( rc==SQLITE4_NOTFOUND ){
  3791   3774       pC->nullRow = 1;
  3792   3775       rc = SQLITE4_OK;
  3793   3776     }
  3794         -  pC->rowidIsValid = 0;
  3795   3777     break;
  3796   3778   }
  3797   3779   
  3798   3780   
  3799   3781   /* Opcode: SorterInsert P1 P2 P3
  3800   3782   */
  3801   3783   /* Opcode: IdxInsert P1 P2 P3 * P5
................................................................................
  4105   4087   
  4106   4088     CHECK_FOR_INTERRUPT;
  4107   4089     pIn1 = &aMem[pOp->p1];
  4108   4090     pOut = &aMem[pOp->p3];
  4109   4091     if( (pIn1->flags & MEM_RowSet)
  4110   4092      && (aKey = sqlite4RowSetRead(pIn1->u.pRowSet, &nKey))
  4111   4093     ){
  4112         -    rc = sqlite4VdbeMemSetStr(pOut, (char const *)aKey, nKey, 0, SQLITE4_TRANSIENT);
         4094  +    rc = sqlite4VdbeMemSetStr(pOut, (char const *)aKey, nKey, 0,
         4095  +                              SQLITE4_TRANSIENT, 0);
  4113   4096       sqlite4RowSetNext(pIn1->u.pRowSet);
  4114   4097     }else{
  4115   4098       /* The RowSet is empty */
  4116   4099       sqlite4VdbeMemSetNull(pIn1);
  4117   4100       pc = pOp->p2 - 1;
  4118   4101     }
  4119   4102   
................................................................................
  4201   4184       assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
  4202   4185       assert( pProgram->nCsr==pFrame->nChildCsr );
  4203   4186       assert( pc==pFrame->pc );
  4204   4187     }
  4205   4188   
  4206   4189     p->nFrame++;
  4207   4190     pFrame->pParent = p->pFrame;
  4208         -  pFrame->lastRowid = lastRowid;
  4209   4191     pFrame->nChange = p->nChange;
  4210   4192     p->nChange = 0;
  4211   4193     p->pFrame = pFrame;
  4212   4194     p->aMem = aMem = &VdbeFrameMem(pFrame)[-1];
  4213   4195     p->nMem = pFrame->nChildMem;
  4214   4196     p->nCursor = (u16)pFrame->nChildCsr;
  4215   4197     p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
................................................................................
  4826   4808         apArg[i] = pX;
  4827   4809         pX++;
  4828   4810       }
  4829   4811       db->vtabOnConflict = pOp->p5;
  4830   4812       rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
  4831   4813       db->vtabOnConflict = vtabOnConflict;
  4832   4814       importVtabErrMsg(p, pVtab);
  4833         -    if( rc==SQLITE4_OK && pOp->p1 ){
  4834         -      assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
  4835         -      db->lastRowid = lastRowid = rowid;
  4836         -    }
  4837   4815       if( rc==SQLITE4_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
  4838   4816         if( pOp->p5==OE_Ignore ){
  4839   4817           rc = SQLITE4_OK;
  4840   4818         }else{
  4841   4819           p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5);
  4842   4820         }
  4843   4821       }else{
................................................................................
  5082   5060       sqlite4ResetInternalSchema(db, resetSchemaOnFault-1);
  5083   5061     }
  5084   5062   
  5085   5063     /* This is the only way out of this procedure.  We have to
  5086   5064     ** release the mutexes on btrees that were acquired at the
  5087   5065     ** top. */
  5088   5066   vdbe_return:
  5089         -  db->lastRowid = lastRowid;
  5090   5067     return rc;
  5091   5068   
  5092   5069     /* Jump to here if a string or blob larger than SQLITE4_MAX_LENGTH
  5093   5070     ** is encountered.
  5094   5071     */
  5095   5072   too_big:
  5096   5073     sqlite4SetString(&p->zErrMsg, db, "string or blob too big");

Changes to src/vdbe.h.

   200    200     int sqlite4VdbeAssertMayAbort(Vdbe *, int);
   201    201     void sqlite4VdbeTrace(Vdbe*,FILE*);
   202    202   #endif
   203    203   void sqlite4VdbeResetStepResult(Vdbe*);
   204    204   void sqlite4VdbeRewind(Vdbe*);
   205    205   int sqlite4VdbeReset(Vdbe*);
   206    206   void sqlite4VdbeSetNumCols(Vdbe*,int);
   207         -int sqlite4VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));
          207  +int sqlite4VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*,void*));
   208    208   void sqlite4VdbeCountChanges(Vdbe*);
   209    209   sqlite4 *sqlite4VdbeDb(Vdbe*);
   210    210   void sqlite4VdbeSetSql(Vdbe*, const char *z, int n);
   211    211   void sqlite4VdbeSwap(Vdbe*,Vdbe*);
   212    212   VdbeOp *sqlite4VdbeTakeOpArray(Vdbe*, int*, int*);
   213    213   sqlite4_value *sqlite4VdbeGetValue(Vdbe*, int, u8);
   214    214   void sqlite4VdbeSetVarmask(Vdbe*, int);

Changes to src/vdbeInt.h.

    54     54     KVStore *pTmpKV;      /* Separate file holding a temporary table */
    55     55     KeyInfo *pKeyInfo;    /* Info about index keys needed by index cursors */
    56     56     int iDb;              /* Index of cursor database in db->aDb[] (or -1) */
    57     57     int iRoot;            /* Root page of the table */
    58     58     int pseudoTableReg;   /* Register holding pseudotable content. */
    59     59     int nField;           /* Number of fields in the header */
    60     60     Bool zeroed;          /* True if zeroed out and ready for reuse */
    61         -  Bool rowidIsValid;    /* True if lastRowid is valid */
    62     61     Bool atFirst;         /* True if pointing to first entry */
    63     62     Bool nullRow;         /* True if pointing to a row with no data */
    64     63     Bool isTable;         /* True if a table requiring integer keys */
    65     64     Bool isIndex;         /* True if an index containing keys only - no data */
    66     65     Bool isOrdered;       /* True if the underlying table is BTREE_UNORDERED */
    67     66     sqlite4_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
    68     67     const sqlite4_module *pModule;     /* Module for cursor pVtabCursor */
    69     68     i64 seqCount;         /* Sequence counter */
    70     69     i64 movetoTarget;     /* Argument to the deferred move-to */
    71         -  i64 lastRowid;        /* Last rowid from a Next or NextIdx operation */
    72     70     VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */
    73     71     Fts5Cursor *pFts;     /* Fts5 cursor object (or NULL) */
    74     72   
    75     73     /* Result of last sqlite4-Moveto() done by an OP_NotExists or 
    76     74     ** OP_IsUnique opcode on this cursor. */
    77     75     int seekResult;
    78     76   };
................................................................................
   109    107     u8 *aOnceFlag;          /* Array of OP_Once flags for parent frame */
   110    108     int nOnceFlag;          /* Number of entries in aOnceFlag */
   111    109     VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
   112    110     u16 nCursor;            /* Number of entries in apCsr */
   113    111     void *token;            /* Copy of SubProgram.token */
   114    112     int nChildMem;          /* Number of memory cells for child frame */
   115    113     int nChildCsr;          /* Number of cursors for child frame */
   116         -  i64 lastRowid;          /* Last insert rowid (sqlite4.lastRowid) */
   117    114     int nChange;            /* Statement changes (Vdbe.nChanges)     */
   118    115     VdbeFrame *pParent;     /* Parent of this frame, or NULL if parent is main */
   119    116   };
   120    117   
   121    118   #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
   122    119   
   123    120   /*
................................................................................
   132    129   */
   133    130   struct Mem {
   134    131     sqlite4 *db;        /* The associated database connection */
   135    132     char *z;            /* String or BLOB value */
   136    133     double r;           /* Real value */
   137    134     union {
   138    135       i64 i;              /* Integer value used when MEM_Int is set in flags */
   139         -    int nZero;          /* Used when bit MEM_Zero is set in flags */
   140    136       FuncDef *pDef;      /* Used only when flags==MEM_Agg */
   141    137       RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
   142    138       VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
   143    139     } u;
   144    140     int n;              /* Number of characters in string value, excluding '\0' */
   145    141     u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
   146    142     u8  type;           /* One of SQLITE4_NULL, SQLITE4_TEXT, SQLITE4_INTEGER, etc */
   147    143     u8  enc;            /* SQLITE4_UTF8, SQLITE4_UTF16BE, SQLITE4_UTF16LE */
   148    144   #ifdef SQLITE4_DEBUG
   149    145     Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
   150    146     void *pFiller;      /* So that sizeof(Mem) is a multiple of 8 */
   151    147   #endif
   152         -  void (*xDel)(void *);  /* If not null, call this function to delete Mem.z */
          148  +  void (*xDel)(void*,void*); /* Function to delete Mem.z */
          149  +  void *pDelArg;             /* First argument to xDel() */
   153    150     char *zMalloc;      /* Dynamic buffer allocated by sqlite4_malloc() */
   154    151   };
   155    152   
   156    153   /* One or more of the following flags are set to indicate the validOK
   157    154   ** representations of the value stored in the Mem struct.
   158    155   **
   159    156   ** If the MEM_Null flag is set, then the value is an SQL NULL value.
................................................................................
   182    179   ** string is \000 or \u0000 terminated
   183    180   */
   184    181   #define MEM_Term      0x0200   /* String rep is nul terminated */
   185    182   #define MEM_Dyn       0x0400   /* Need to call sqliteFree() on Mem.z */
   186    183   #define MEM_Static    0x0800   /* Mem.z points to a static string */
   187    184   #define MEM_Ephem     0x1000   /* Mem.z points to an ephemeral string */
   188    185   #define MEM_Agg       0x2000   /* Mem.z points to an agg function context */
   189         -#define MEM_Zero      0x4000   /* Mem.i contains count of 0s appended to blob */
   190    186   
   191    187   /*
   192    188   ** Clear any existing type flags from a Mem and replace them with f
   193    189   */
   194    190   #define MemSetTypeFlag(p, f) \
   195         -   ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)
          191  +   ((p)->flags = ((p)->flags&~(MEM_TypeMask))|f)
   196    192   
   197    193   /*
   198    194   ** Return true if a memory cell is not marked as invalid.  This macro
   199    195   ** is for use inside assert() statements only.
   200    196   */
   201    197   #ifdef SQLITE4_DEBUG
   202    198   #define memIsValid(M)  ((M)->flags & MEM_Invalid)==0
................................................................................
   213    209   ** invocations.
   214    210   */
   215    211   struct VdbeFunc {
   216    212     FuncDef *pFunc;               /* The definition of the function */
   217    213     int nAux;                     /* Number of entries allocated for apAux[] */
   218    214     struct AuxData {
   219    215       void *pAux;                   /* Aux data for the i-th argument */
   220         -    void (*xDelete)(void *);      /* Destructor for the aux data */
          216  +    void (*xDelete)(void*,void*); /* Destructor for the aux data */
          217  +    void *pDeleteArg;             /* First argument to xDelete */
   221    218     } apAux[1];                   /* One slot for each function argument */
   222    219   };
   223    220   
   224    221   /*
   225    222   ** The "context" argument for a installable function.  A pointer to an
   226    223   ** instance of this structure is the first argument to the routines used
   227    224   ** implement the SQL functions.
................................................................................
   375    372     u8 **pzOut,                 /* The output data record */
   376    373     int *pnOut                  /* Bytes of content in pzOut */
   377    374   );
   378    375   int sqlite4VdbeEncodeKey(
   379    376     sqlite4 *db,                 /* The database connection */
   380    377     Mem *aIn,                    /* Values to be encoded */
   381    378     int nIn,                     /* Number of entries in aIn[] */
          379  +  int nInTotal,                /* Number of values in complete key */
   382    380     int iTabno,                  /* The table this key applies to */
   383    381     KeyInfo *pKeyInfo,           /* Collating sequence information */
   384    382     u8 **pzOut,                  /* Write the resulting key here */
   385    383     int *pnOut,                  /* Number of bytes in the key */
   386         -  int bIncr                    /* Make the key "incrementable" */
          384  +  int nExtra                   /* Append extra bytes on end of key */
   387    385   );
   388    386   int sqlite4VdbeEncodeIntKey(u8 *aBuf,sqlite4_int64 v);
   389    387   int sqlite4VdbeDecodeIntKey(const KVByteArray*, KVSize, sqlite4_int64*);
   390    388   int sqlite4VdbeShortKey(const u8 *, int, int);
   391    389   int sqlite4MemCompare(const Mem*, const Mem*, const CollSeq*);
   392    390   int sqlite4VdbeExec(Vdbe*);
   393    391   int sqlite4VdbeList(Vdbe*);
................................................................................
   394    392   int sqlite4VdbeHalt(Vdbe*);
   395    393   int sqlite4VdbeChangeEncoding(Mem *, int);
   396    394   int sqlite4VdbeMemTooBig(Mem*);
   397    395   int sqlite4VdbeMemCopy(Mem*, const Mem*);
   398    396   void sqlite4VdbeMemShallowCopy(Mem*, const Mem*, int);
   399    397   void sqlite4VdbeMemMove(Mem*, Mem*);
   400    398   int sqlite4VdbeMemNulTerminate(Mem*);
   401         -int sqlite4VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*));
          399  +int sqlite4VdbeMemSetStr(Mem*, const char*, int, u8,
          400  +                         void(*)(void*,void*),void*);
   402    401   void sqlite4VdbeMemSetInt64(Mem*, i64);
   403    402   #ifdef SQLITE4_OMIT_FLOATING_POINT
   404    403   # define sqlite4VdbeMemSetDouble sqlite4VdbeMemSetInt64
   405    404   #else
   406    405     void sqlite4VdbeMemSetDouble(Mem*, double);
   407    406   #endif
   408    407   void sqlite4VdbeMemSetNull(Mem*);
   409         -void sqlite4VdbeMemSetZeroBlob(Mem*,int);
   410    408   int sqlite4VdbeMemMakeWriteable(Mem*);
   411    409   int sqlite4VdbeMemStringify(Mem*, int);
   412    410   i64 sqlite4VdbeIntValue(Mem*);
   413    411   int sqlite4VdbeMemIntegerify(Mem*);
   414    412   double sqlite4VdbeRealValue(Mem*);
   415    413   void sqlite4VdbeIntegerAffinity(Mem*);
   416    414   int sqlite4VdbeMemRealify(Mem*);
................................................................................
   451    449   #ifdef SQLITE4_DEBUG
   452    450     void sqlite4VdbePrintSql(Vdbe*);
   453    451     void sqlite4VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
   454    452   #endif
   455    453   int sqlite4VdbeMemHandleBom(Mem *pMem);
   456    454   
   457    455   
   458         -#define sqlite4VdbeMemExpandBlob(x) SQLITE4_OK
   459         -#define ExpandBlob(P) SQLITE4_OK
   460         -
   461    456   #endif /* !defined(_VDBEINT_H_) */

Changes to src/vdbeapi.c.

    12     12   **
    13     13   ** This file contains code use to implement APIs that are part of the
    14     14   ** VDBE.
    15     15   */
    16     16   #include "sqliteInt.h"
    17     17   #include "vdbeInt.h"
    18     18   
    19         -#ifndef SQLITE4_OMIT_DEPRECATED
    20         -/*
    21         -** Return TRUE (non-zero) of the statement supplied as an argument needs
    22         -** to be recompiled.  A statement needs to be recompiled whenever the
    23         -** execution environment changes in a way that would alter the program
    24         -** that sqlite4_prepare() generates.  For example, if new functions or
    25         -** collating sequences are registered or if an authorizer function is
    26         -** added or changed.
    27         -*/
    28         -int sqlite4_expired(sqlite4_stmt *pStmt){
    29         -  Vdbe *p = (Vdbe*)pStmt;
    30         -  return p==0 || p->expired;
    31         -}
    32         -#endif
    33         -
    34     19   /*
    35     20   ** Check on a Vdbe to make sure it has not been finalized.  Log
    36     21   ** an error and return true if it has been finalized (or is otherwise
    37     22   ** invalid).  Return false if it is ok.
    38     23   */
    39     24   static int vdbeSafety(Vdbe *p){
    40     25     if( p->db==0 ){
................................................................................
   135    120   /**************************** sqlite4_value_  *******************************
   136    121   ** The following routines extract information from a Mem or sqlite4_value
   137    122   ** structure.
   138    123   */
   139    124   const void *sqlite4_value_blob(sqlite4_value *pVal){
   140    125     Mem *p = (Mem*)pVal;
   141    126     if( p->flags & (MEM_Blob|MEM_Str) ){
   142         -   (void)sqlite4VdbeMemExpandBlob(p);
   143    127       p->flags &= ~MEM_Str;
   144    128       p->flags |= MEM_Blob;
   145    129       return p->n ? p->z : 0;
   146    130     }else{
   147    131       return sqlite4_value_text(pVal);
   148    132     }
   149    133   }
................................................................................
   185    169   ** the function result.
   186    170   **
   187    171   ** The setStrOrError() funtion calls sqlite4VdbeMemSetStr() to store the
   188    172   ** result as a string or blob but if the string or blob is too large, it
   189    173   ** then sets the error code to SQLITE4_TOOBIG
   190    174   */
   191    175   static void setResultStrOrError(
   192         -  sqlite4_context *pCtx,  /* Function context */
   193         -  const char *z,          /* String pointer */
   194         -  int n,                  /* Bytes in string, or negative */
   195         -  u8 enc,                 /* Encoding of z.  0 for BLOBs */
   196         -  void (*xDel)(void*)     /* Destructor function */
          176  +  sqlite4_context *pCtx,     /* Function context */
          177  +  const char *z,             /* String pointer */
          178  +  int n,                     /* Bytes in string, or negative */
          179  +  u8 enc,                    /* Encoding of z.  0 for BLOBs */
          180  +  void (*xDel)(void*,void*), /* Destructor function */
          181  +  void *pDelArg              /* First argument to xDel() */
   197    182   ){
   198    183     if( xDel==SQLITE4_DYNAMIC ){
   199    184       assert( sqlite4MemdebugHasType(z, MEMTYPE_HEAP) );
   200    185       assert( sqlite4MemdebugNoType(z, ~MEMTYPE_HEAP) );
   201    186       sqlite4MemdebugSetType((char*)z, MEMTYPE_DB | MEMTYPE_HEAP);
   202    187     }
   203         -  if( sqlite4VdbeMemSetStr(&pCtx->s, z, n, enc, xDel)==SQLITE4_TOOBIG ){
          188  +  if( sqlite4VdbeMemSetStr(&pCtx->s, z, n, enc, xDel,pDelArg)==SQLITE4_TOOBIG ){
   204    189       sqlite4_result_error_toobig(pCtx);
   205    190     }
   206    191   }
   207    192   void sqlite4_result_blob(
   208    193     sqlite4_context *pCtx, 
   209    194     const void *z, 
   210    195     int n, 
   211         -  void (*xDel)(void *)
          196  +  void (*xDel)(void*,void*),
          197  +  void *pDelArg
   212    198   ){
   213    199     assert( n>=0 );
   214    200     assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
   215         -  setResultStrOrError(pCtx, z, n, 0, xDel);
          201  +  setResultStrOrError(pCtx, z, n, 0, xDel, pDelArg);
   216    202   }
   217    203   void sqlite4_result_double(sqlite4_context *pCtx, double rVal){
   218    204     assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
   219    205     sqlite4VdbeMemSetDouble(&pCtx->s, rVal);
   220    206   }
   221    207   void sqlite4_result_error(sqlite4_context *pCtx, const char *z, int n){
   222    208     assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
   223    209     pCtx->isError = SQLITE4_ERROR;
   224         -  sqlite4VdbeMemSetStr(&pCtx->s, z, n, SQLITE4_UTF8, SQLITE4_TRANSIENT);
          210  +  sqlite4VdbeMemSetStr(&pCtx->s, z, n, SQLITE4_UTF8, SQLITE4_TRANSIENT, 0);
   225    211   }
   226    212   #ifndef SQLITE4_OMIT_UTF16
   227    213   void sqlite4_result_error16(sqlite4_context *pCtx, const void *z, int n){
   228    214     assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
   229    215     pCtx->isError = SQLITE4_ERROR;
   230         -  sqlite4VdbeMemSetStr(&pCtx->s, z, n, SQLITE4_UTF16NATIVE, SQLITE4_TRANSIENT);
          216  +  sqlite4VdbeMemSetStr(&pCtx->s, z, n, SQLITE4_UTF16NATIVE,SQLITE4_TRANSIENT,0);
   231    217   }
   232    218   #endif
   233    219   void sqlite4_result_int(sqlite4_context *pCtx, int iVal){
   234    220     assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
   235    221     sqlite4VdbeMemSetInt64(&pCtx->s, (i64)iVal);
   236    222   }
   237    223   void sqlite4_result_int64(sqlite4_context *pCtx, i64 iVal){
................................................................................
   242    228     assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
   243    229     sqlite4VdbeMemSetNull(&pCtx->s);
   244    230   }
   245    231   void sqlite4_result_text(
   246    232     sqlite4_context *pCtx, 
   247    233     const char *z, 
   248    234     int n,
   249         -  void (*xDel)(void *)
          235  +  void (*xDel)(void*,void*),
          236  +  void *pDelArg
   250    237   ){
   251    238     assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
   252         -  setResultStrOrError(pCtx, z, n, SQLITE4_UTF8, xDel);
          239  +  setResultStrOrError(pCtx, z, n, SQLITE4_UTF8, xDel, pDelArg);
   253    240   }
   254    241   #ifndef SQLITE4_OMIT_UTF16
   255    242   void sqlite4_result_text16(
   256    243     sqlite4_context *pCtx, 
   257    244     const void *z, 
   258    245     int n, 
   259         -  void (*xDel)(void *)
          246  +  void (*xDel)(void*,void*),
          247  +  void *pDelArg
   260    248   ){
   261    249     assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
   262         -  setResultStrOrError(pCtx, z, n, SQLITE4_UTF16NATIVE, xDel);
          250  +  setResultStrOrError(pCtx, z, n, SQLITE4_UTF16NATIVE, xDel, pDelArg);
   263    251   }
   264    252   void sqlite4_result_text16be(
   265    253     sqlite4_context *pCtx, 
   266    254     const void *z, 
   267    255     int n, 
   268         -  void (*xDel)(void *)
          256  +  void (*xDel)(void*,void*),
          257  +  void *pDelArg
   269    258   ){
   270    259     assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
   271         -  setResultStrOrError(pCtx, z, n, SQLITE4_UTF16BE, xDel);
          260  +  setResultStrOrError(pCtx, z, n, SQLITE4_UTF16BE, xDel, pDelArg);
   272    261   }
   273    262   void sqlite4_result_text16le(
   274    263     sqlite4_context *pCtx, 
   275    264     const void *z, 
   276    265     int n, 
   277         -  void (*xDel)(void *)
          266  +  void (*xDel)(void*,void*),
          267  +  void *pDelArg
   278    268   ){
   279    269     assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
   280         -  setResultStrOrError(pCtx, z, n, SQLITE4_UTF16LE, xDel);
          270  +  setResultStrOrError(pCtx, z, n, SQLITE4_UTF16LE, xDel, pDelArg);
   281    271   }
   282    272   #endif /* SQLITE4_OMIT_UTF16 */
   283    273   void sqlite4_result_value(sqlite4_context *pCtx, sqlite4_value *pValue){
   284    274     assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
   285    275     sqlite4VdbeMemCopy(&pCtx->s, pValue);
   286    276   }
   287         -void sqlite4_result_zeroblob(sqlite4_context *pCtx, int n){
   288         -  assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
   289         -  sqlite4VdbeMemSetZeroBlob(&pCtx->s, n);
   290         -}
   291    277   void sqlite4_result_error_code(sqlite4_context *pCtx, int errCode){
   292    278     pCtx->isError = errCode;
   293    279     if( pCtx->s.flags & MEM_Null ){
   294    280       sqlite4VdbeMemSetStr(&pCtx->s, sqlite4ErrStr(errCode), -1, 
   295         -                         SQLITE4_UTF8, SQLITE4_STATIC);
          281  +                         SQLITE4_UTF8, SQLITE4_STATIC, 0);
   296    282     }
   297    283   }
   298    284   
   299    285   /* Force an SQLITE4_TOOBIG error. */
   300    286   void sqlite4_result_error_toobig(sqlite4_context *pCtx){
   301    287     assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
   302    288     pCtx->isError = SQLITE4_TOOBIG;
   303    289     sqlite4VdbeMemSetStr(&pCtx->s, "string or blob too big", -1, 
   304         -                       SQLITE4_UTF8, SQLITE4_STATIC);
          290  +                       SQLITE4_UTF8, SQLITE4_STATIC, 0);
   305    291   }
   306    292   
   307    293   /* An SQLITE4_NOMEM error. */
   308    294   void sqlite4_result_error_nomem(sqlite4_context *pCtx){
   309    295     assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
   310    296     sqlite4VdbeMemSetNull(&pCtx->s);
   311    297     pCtx->isError = SQLITE4_NOMEM;
................................................................................
   587    573   ** argument to the user-function defined by pCtx. Any previous value is
   588    574   ** deleted by calling the delete function specified when it was set.
   589    575   */
   590    576   void sqlite4_set_auxdata(
   591    577     sqlite4_context *pCtx, 
   592    578     int iArg, 
   593    579     void *pAux, 
   594         -  void (*xDelete)(void*)
          580  +  void (*xDelete)(void*,void*),
          581  +  void *pDeleteArg
   595    582   ){
   596    583     struct AuxData *pAuxData;
   597    584     VdbeFunc *pVdbeFunc;
   598    585     if( iArg<0 ) goto failed;
   599    586   
   600    587     assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
   601    588     pVdbeFunc = pCtx->pVdbeFunc;
................................................................................
   610    597       memset(&pVdbeFunc->apAux[nAux], 0, sizeof(struct AuxData)*(iArg+1-nAux));
   611    598       pVdbeFunc->nAux = iArg+1;
   612    599       pVdbeFunc->pFunc = pCtx->pFunc;
   613    600     }
   614    601   
   615    602     pAuxData = &pVdbeFunc->apAux[iArg];
   616    603     if( pAuxData->pAux && pAuxData->xDelete ){
   617         -    pAuxData->xDelete(pAuxData->pAux);
          604  +    pAuxData->xDelete(pAuxData->pDeleteArg, pAuxData->pAux);
   618    605     }
   619    606     pAuxData->pAux = pAux;
   620    607     pAuxData->xDelete = xDelete;
          608  +  pAuxData->pDeleteArg = pDeleteArg;
   621    609     return;
   622    610   
   623    611   failed:
   624    612     if( xDelete ){
   625         -    xDelete(pAux);
          613  +    xDelete(pDeleteArg, pAux);
   626    614     }
   627    615   }
   628    616   
   629         -#ifndef SQLITE4_OMIT_DEPRECATED
   630         -/*
   631         -** Return the number of times the Step function of a aggregate has been 
   632         -** called.
   633         -**
   634         -** This function is deprecated.  Do not use it for new code.  It is
   635         -** provide only to avoid breaking legacy code.  New aggregate function
   636         -** implementations should keep their own counts within their aggregate
   637         -** context.
   638         -*/
   639         -int sqlite4_aggregate_count(sqlite4_context *p){
   640         -  assert( p && p->pMem && p->pFunc && p->pFunc->xStep );
   641         -  return p->pMem->n;
   642         -}
   643         -#endif
   644         -
   645    617   /*
   646    618   ** Return the number of columns in the result set for the statement pStmt.
   647    619   */
   648    620   int sqlite4_column_count(sqlite4_stmt *pStmt){
   649    621     Vdbe *pVm = (Vdbe *)pStmt;
   650    622     return pVm ? pVm->nResColumn : 0;
   651    623   }
................................................................................
   741    713   /**************************** sqlite4_column_  *******************************
   742    714   ** The following routines are used to access elements of the current row
   743    715   ** in the result set.
   744    716   */
   745    717   const void *sqlite4_column_blob(sqlite4_stmt *pStmt, int i){
   746    718     const void *val;
   747    719     val = sqlite4_value_blob( columnMem(pStmt,i) );
   748         -  /* Even though there is no encoding conversion, value_blob() might
   749         -  ** need to call malloc() to expand the result of a zeroblob() 
   750         -  ** expression. 
   751         -  */
   752         -  columnMallocFailure(pStmt);
   753    720     return val;
   754    721   }
   755    722   int sqlite4_column_bytes(sqlite4_stmt *pStmt, int i){
   756    723     int val = sqlite4_value_bytes( columnMem(pStmt,i) );
   757    724     columnMallocFailure(pStmt);
   758    725     return val;
   759    726   }
................................................................................
  1004    971     return SQLITE4_OK;
  1005    972   }
  1006    973   
  1007    974   /*
  1008    975   ** Bind a text or BLOB value.
  1009    976   */
  1010    977   static int bindText(
  1011         -  sqlite4_stmt *pStmt,   /* The statement to bind against */
  1012         -  int i,                 /* Index of the parameter to bind */
  1013         -  const void *zData,     /* Pointer to the data to be bound */
  1014         -  int nData,             /* Number of bytes of data to be bound */
  1015         -  void (*xDel)(void*),   /* Destructor for the data */
  1016         -  u8 encoding            /* Encoding for the data */
          978  +  sqlite4_stmt *pStmt,       /* The statement to bind against */
          979  +  int i,                     /* Index of the parameter to bind */
          980  +  const void *zData,         /* Pointer to the data to be bound */
          981  +  int nData,                 /* Number of bytes of data to be bound */
          982  +  void (*xDel)(void*,void*), /* Destructor for the data */
          983  +  void *pDelArg,             /* First argument to xDel() */
          984  +  u8 encoding                /* Encoding for the data */
  1017    985   ){
  1018    986     Vdbe *p = (Vdbe *)pStmt;
  1019    987     Mem *pVar;
  1020    988     int rc;
  1021    989   
  1022    990     rc = vdbeUnbind(p, i);
  1023    991     if( rc==SQLITE4_OK ){
  1024    992       if( zData!=0 ){
  1025    993         pVar = &p->aVar[i-1];
  1026         -      rc = sqlite4VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
          994  +      rc = sqlite4VdbeMemSetStr(pVar, zData, nData, encoding, xDel, pDelArg);
  1027    995         if( rc==SQLITE4_OK && encoding!=0 ){
  1028    996           rc = sqlite4VdbeChangeEncoding(pVar, ENC(p->db));
  1029    997         }
  1030    998         sqlite4Error(p->db, rc, 0);
  1031    999         rc = sqlite4ApiExit(p->db, rc);
  1032   1000       }
  1033   1001       sqlite4_mutex_leave(p->db->mutex);
  1034   1002     }else if( xDel!=SQLITE4_STATIC && xDel!=SQLITE4_TRANSIENT ){
  1035         -    xDel((void*)zData);
         1003  +    xDel(pDelArg, (void*)zData);
  1036   1004     }
  1037   1005     return rc;
  1038   1006   }
  1039   1007   
  1040   1008   
  1041   1009   /*
  1042   1010   ** Bind a blob value to an SQL statement variable.
  1043   1011   */
  1044   1012   int sqlite4_bind_blob(
  1045   1013     sqlite4_stmt *pStmt, 
  1046   1014     int i, 
  1047   1015     const void *zData, 
  1048   1016     int nData, 
  1049         -  void (*xDel)(void*)
         1017  +  void (*xDel)(void*,void*),
         1018  +  void *pDelArg
  1050   1019   ){
  1051         -  return bindText(pStmt, i, zData, nData, xDel, 0);
         1020  +  return bindText(pStmt, i, zData, nData, xDel, pDelArg, 0);
  1052   1021   }
  1053   1022   int sqlite4_bind_double(sqlite4_stmt *pStmt, int i, double rValue){
  1054   1023     int rc;
  1055   1024     Vdbe *p = (Vdbe *)pStmt;
  1056   1025     rc = vdbeUnbind(p, i);
  1057   1026     if( rc==SQLITE4_OK ){
  1058   1027       sqlite4VdbeMemSetDouble(&p->aVar[i-1], rValue);
................................................................................
  1083   1052     return rc;
  1084   1053   }
  1085   1054   int sqlite4_bind_text( 
  1086   1055     sqlite4_stmt *pStmt, 
  1087   1056     int i, 
  1088   1057     const char *zData, 
  1089   1058     int nData, 
  1090         -  void (*xDel)(void*)
         1059  +  void (*xDel)(void*,void*),
         1060  +  void *pDelArg
  1091   1061   ){
  1092         -  return bindText(pStmt, i, zData, nData, xDel, SQLITE4_UTF8);
         1062  +  return bindText(pStmt, i, zData, nData, xDel, pDelArg, SQLITE4_UTF8);
  1093   1063   }
  1094   1064   #ifndef SQLITE4_OMIT_UTF16
  1095   1065   int sqlite4_bind_text16(
  1096   1066     sqlite4_stmt *pStmt, 
  1097   1067     int i, 
  1098   1068     const void *zData, 
  1099   1069     int nData, 
  1100         -  void (*xDel)(void*)
         1070  +  void (*xDel)(void*,void*),
         1071  +  void *pDelArg
  1101   1072   ){
  1102         -  return bindText(pStmt, i, zData, nData, xDel, SQLITE4_UTF16NATIVE);
         1073  +  return bindText(pStmt, i, zData, nData, xDel, pDelArg, SQLITE4_UTF16NATIVE);
  1103   1074   }
  1104   1075   #endif /* SQLITE4_OMIT_UTF16 */
  1105   1076   int sqlite4_bind_value(sqlite4_stmt *pStmt, int i, const sqlite4_value *pValue){
  1106   1077     int rc;
  1107   1078     switch( pValue->type ){
  1108   1079       case SQLITE4_INTEGER: {
  1109   1080         rc = sqlite4_bind_int64(pStmt, i, pValue->u.i);
................................................................................
  1110   1081         break;
  1111   1082       }
  1112   1083       case SQLITE4_FLOAT: {
  1113   1084         rc = sqlite4_bind_double(pStmt, i, pValue->r);
  1114   1085         break;
  1115   1086       }
  1116   1087       case SQLITE4_BLOB: {
  1117         -      if( pValue->flags & MEM_Zero ){
  1118         -        rc = sqlite4_bind_zeroblob(pStmt, i, pValue->u.nZero);
  1119         -      }else{
  1120         -        rc = sqlite4_bind_blob(pStmt, i, pValue->z, pValue->n,SQLITE4_TRANSIENT);
  1121         -      }
         1088  +      rc = sqlite4_bind_blob(pStmt, i, pValue->z, pValue->n,
         1089  +                             SQLITE4_TRANSIENT, 0);
  1122   1090         break;
  1123   1091       }
  1124   1092       case SQLITE4_TEXT: {
  1125         -      rc = bindText(pStmt,i,  pValue->z, pValue->n, SQLITE4_TRANSIENT,
         1093  +      rc = bindText(pStmt,i,  pValue->z, pValue->n, SQLITE4_TRANSIENT, 0,
  1126   1094                                 pValue->enc);
  1127   1095         break;
  1128   1096       }
  1129   1097       default: {
  1130   1098         rc = sqlite4_bind_null(pStmt, i);
  1131   1099         break;
  1132   1100       }
  1133   1101     }
  1134         -  return rc;
  1135         -}
  1136         -int sqlite4_bind_zeroblob(sqlite4_stmt *pStmt, int i, int n){
  1137         -  int rc;
  1138         -  Vdbe *p = (Vdbe *)pStmt;
  1139         -  rc = vdbeUnbind(p, i);
  1140         -  if( rc==SQLITE4_OK ){
  1141         -    sqlite4VdbeMemSetZeroBlob(&p->aVar[i-1], n);
  1142         -    sqlite4_mutex_leave(p->db->mutex);
  1143         -  }
  1144   1102     return rc;
  1145   1103   }
  1146   1104   
  1147   1105   /*
  1148   1106   ** Return the number of wildcards that can be potentially bound to.
  1149   1107   ** This routine is added to support DBD::SQLite.  
  1150   1108   */
................................................................................
  1204   1162     for(i=0; i<pFrom->nVar; i++){
  1205   1163       sqlite4VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
  1206   1164     }
  1207   1165     sqlite4_mutex_leave(pTo->db->mutex);
  1208   1166     return SQLITE4_OK;
  1209   1167   }
  1210   1168   
  1211         -#ifndef SQLITE4_OMIT_DEPRECATED
  1212         -/*
  1213         -** Deprecated external interface.  Internal/core SQLite code
  1214         -** should call sqlite4TransferBindings.
  1215         -**
  1216         -** Is is misuse to call this routine with statements from different
  1217         -** database connections.  But as this is a deprecated interface, we
  1218         -** will not bother to check for that condition.
  1219         -**
  1220         -** If the two statements contain a different number of bindings, then
  1221         -** an SQLITE4_ERROR is returned.  Nothing else can go wrong, so otherwise
  1222         -** SQLITE4_OK is returned.
  1223         -*/
  1224         -int sqlite4_transfer_bindings(sqlite4_stmt *pFromStmt, sqlite4_stmt *pToStmt){
  1225         -  Vdbe *pFrom = (Vdbe*)pFromStmt;
  1226         -  Vdbe *pTo = (Vdbe*)pToStmt;
  1227         -  if( pFrom->nVar!=pTo->nVar ){
  1228         -    return SQLITE4_ERROR;
  1229         -  }
  1230         -  if( pTo->expmask ){
  1231         -    pTo->expired = 1;
  1232         -  }
  1233         -  if( pFrom->expmask ){
  1234         -    pFrom->expired = 1;
  1235         -  }
  1236         -  return sqlite4TransferBindings(pFromStmt, pToStmt);
  1237         -}
  1238         -#endif
  1239         -
  1240   1169   /*
  1241   1170   ** Return the sqlite4* database handle to which the prepared statement given
  1242   1171   ** in the argument belongs.  This is the same database handle that was
  1243   1172   ** the first argument to the sqlite4_prepare() that was used to create
  1244   1173   ** the statement in the first place.
  1245   1174   */
  1246   1175   sqlite4 *sqlite4_db_handle(sqlite4_stmt *pStmt){

Changes to src/vdbeaux.c.

    14     14   ** to version 2.8.7, all this code was combined into the vdbe.c source file.
    15     15   ** But that file was getting too big so this subroutines were split out.
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   #include "vdbeInt.h"
    19     19   
    20     20   
    21         -
    22         -/*
    23         -** When debugging the code generator in a symbolic debugger, one can
    24         -** set the sqlite4VdbeAddopTrace to 1 and all opcodes will be printed
    25         -** as they are added to the instruction stream.
    26         -*/
    27         -#ifdef SQLITE4_DEBUG
    28         -int sqlite4VdbeAddopTrace = 0;
    29         -#endif
    30         -
    31         -
    32     21   /*
    33     22   ** Create a new virtual database engine.
    34     23   */
    35     24   Vdbe *sqlite4VdbeCreate(sqlite4 *db){
    36     25     Vdbe *p;
    37     26     p = sqlite4DbMallocZero(db, sizeof(Vdbe) );
    38     27     if( p==0 ) return 0;
................................................................................
   148    137     pOp->p1 = p1;
   149    138     pOp->p2 = p2;
   150    139     pOp->p3 = p3;
   151    140     pOp->p4.p = 0;
   152    141     pOp->p4type = P4_NOTUSED;
   153    142   #ifdef SQLITE4_DEBUG
   154    143     pOp->zComment = 0;
   155         -  if( sqlite4VdbeAddopTrace ) sqlite4VdbePrintOp(0, i, &p->aOp[i]);
          144  +  if( p->db->flags & SQLITE4_VdbeAddopTrace ){
          145  +    sqlite4VdbePrintOp(0, i, &p->aOp[i]);
          146  +  }
   156    147   #endif
   157    148   #ifdef VDBE_PROFILE
   158    149     pOp->cycles = 0;
   159    150     pOp->cnt = 0;
   160    151   #endif
   161    152     return i;
   162    153   }
................................................................................
   501    492         }
   502    493         pOut->p3 = pIn->p3;
   503    494         pOut->p4type = P4_NOTUSED;
   504    495         pOut->p4.p = 0;
   505    496         pOut->p5 = 0;
   506    497   #ifdef SQLITE4_DEBUG
   507    498         pOut->zComment = 0;
   508         -      if( sqlite4VdbeAddopTrace ){
          499  +      if( p->db->flags & SQLITE4_VdbeAddopTrace ){
   509    500           sqlite4VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
   510    501         }
   511    502   #endif
   512    503       }
   513    504       p->nOp += nOp;
   514    505     }
   515    506     return addr;
................................................................................
  1191   1182       if( sqlite4VdbeMemGrow(pMem, 32, 0) ){            /* P4 */
  1192   1183         assert( p->db->mallocFailed );
  1193   1184         return SQLITE4_ERROR;
  1194   1185       }
  1195   1186       pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
  1196   1187       z = displayP4(pOp, pMem->z, 32);
  1197   1188       if( z!=pMem->z ){
  1198         -      sqlite4VdbeMemSetStr(pMem, z, -1, SQLITE4_UTF8, 0);
         1189  +      sqlite4VdbeMemSetStr(pMem, z, -1, SQLITE4_UTF8, 0, 0);
  1199   1190       }else{
  1200   1191         assert( pMem->z!=0 );
  1201   1192         pMem->n = sqlite4Strlen30(pMem->z);
  1202   1193         pMem->enc = SQLITE4_UTF8;
  1203   1194       }
  1204   1195       pMem->type = SQLITE4_TEXT;
  1205   1196       pMem++;
................................................................................
  1529   1520     v->nOnceFlag = pFrame->nOnceFlag;
  1530   1521     v->aOp = pFrame->aOp;
  1531   1522     v->nOp = pFrame->nOp;
  1532   1523     v->aMem = pFrame->aMem;
  1533   1524     v->nMem = pFrame->nMem;
  1534   1525     v->apCsr = pFrame->apCsr;
  1535   1526     v->nCursor = pFrame->nCursor;
  1536         -  v->db->lastRowid = pFrame->lastRowid;
  1537   1527     v->nChange = pFrame->nChange;
  1538   1528     return pFrame->pc;
  1539   1529   }
  1540   1530   
  1541   1531   /*
  1542   1532   ** Close all cursors.
  1543   1533   **
................................................................................
  1634   1624   ** to by zName will be freed by sqlite4DbFree() when the vdbe is destroyed.
  1635   1625   */
  1636   1626   int sqlite4VdbeSetColName(
  1637   1627     Vdbe *p,                         /* Vdbe being configured */
  1638   1628     int idx,                         /* Index of column zName applies to */
  1639   1629     int var,                         /* One of the COLNAME_* constants */
  1640   1630     const char *zName,               /* Pointer to buffer containing name */
  1641         -  void (*xDel)(void*)              /* Memory management strategy for zName */
         1631  +  void (*xDel)(void*,void*)        /* Memory management strategy for zName */
  1642   1632   ){
  1643   1633     int rc;
  1644   1634     Mem *pColName;
  1645   1635     assert( idx<p->nResColumn );
  1646   1636     assert( var<COLNAME_N );
         1637  +  assert( xDel==SQLITE4_STATIC || xDel==SQLITE4_TRANSIENT
         1638  +             || xDel==SQLITE4_DYNAMIC );
  1647   1639     if( p->db->mallocFailed ){
  1648   1640       assert( !zName || xDel!=SQLITE4_DYNAMIC );
  1649   1641       return SQLITE4_NOMEM;
  1650   1642     }
  1651   1643     assert( p->aColName!=0 );
  1652   1644     pColName = &(p->aColName[idx+var*p->nResColumn]);
  1653         -  rc = sqlite4VdbeMemSetStr(pColName, zName, -1, SQLITE4_UTF8, xDel);
         1645  +  rc = sqlite4VdbeMemSetStr(pColName, zName, -1, SQLITE4_UTF8, xDel, 0);
  1654   1646     assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 );
  1655   1647     return rc;
  1656   1648   }
  1657   1649   
  1658   1650   /*
  1659   1651   ** Free all Savepoint structures that correspond to transaction levels
  1660   1652   ** larger than iLevel. Passing iLevel==1 deletes all Savepoint structures.
................................................................................
  1972   1964   */
  1973   1965   int sqlite4VdbeTransferError(Vdbe *p){
  1974   1966     sqlite4 *db = p->db;
  1975   1967     int rc = p->rc;
  1976   1968     if( p->zErrMsg ){
  1977   1969       u8 mallocFailed = db->mallocFailed;
  1978   1970       sqlite4BeginBenignMalloc(db->pEnv);
  1979         -    sqlite4ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE4_UTF8, SQLITE4_TRANSIENT);
         1971  +    sqlite4ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE4_UTF8,
         1972  +                       SQLITE4_TRANSIENT, 0);
  1980   1973       sqlite4EndBenignMalloc(db->pEnv);
  1981   1974       db->mallocFailed = mallocFailed;
  1982   1975       db->errCode = rc;
  1983   1976     }else{
  1984   1977       sqlite4Error(db, rc, 0);
  1985   1978     }
  1986   1979     return rc;
................................................................................
  2019   2012       if( p->runOnlyOnce ) p->expired = 1;
  2020   2013     }else if( p->rc && p->expired ){
  2021   2014       /* The expired flag was set on the VDBE before the first call
  2022   2015       ** to sqlite4_step(). For consistency (since sqlite4_step() was
  2023   2016       ** called), set the database error in this case as well.
  2024   2017       */
  2025   2018       sqlite4Error(db, p->rc, 0);
  2026         -    sqlite4ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE4_UTF8, SQLITE4_TRANSIENT);
         2019  +    sqlite4ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE4_UTF8,
         2020  +                       SQLITE4_TRANSIENT, 0);
  2027   2021       sqlite4DbFree(db, p->zErrMsg);
  2028   2022       p->zErrMsg = 0;
  2029   2023     }
  2030   2024   
  2031   2025     /* Reclaim all memory used by the VDBE
  2032   2026     */
  2033   2027     Cleanup(p);
...............................................................................