/ Check-in [214f8cda]
Login

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

Overview
Comment:Update sorter-coalesce-writes branch with latest trunk changes.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sorter-coalesce-writes
Files: files | file ages | folders
SHA1: 214f8cda1727e0eee51605be487d4cf4f2dfb6db
User & Date: dan 2012-08-06 18:10:09
Context
2012-08-06
18:50
When reusing pages as part of creating a new index, allocate the leaves from each free-list trunk page in ascending order, instead of trying to maximize localization for each individual allocation. This increases the chance that pages will be written to disk in ascending order by a large CREATE INDEX statement, improving overall performance. check-in: d045f8b2 user: dan tags: sorter-coalesce-writes
18:10
Update sorter-coalesce-writes branch with latest trunk changes. check-in: 214f8cda user: dan tags: sorter-coalesce-writes
10:51
Update description strings in the VSIX package. check-in: 541e9310 user: mistachkin tags: trunk
2012-07-26
09:21
Update some comments in vdbesort.c. check-in: f4b3fded user: dan tags: sorter-coalesce-writes
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   937    937   	rm -rf quota2a quota2b quota2c
   938    938   	rm -rf tsrc .target_source
   939    939   	rm -f tclsqlite3$(TEXE)
   940    940   	rm -f testfixture$(TEXE) test.db
   941    941   	rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
   942    942   	rm -f sqlite3.c
   943    943   	rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
          944  +	rm -f sqlite-output.vsix
   944    945   
   945    946   distclean:	clean
   946    947   	rm -f config.log config.status libtool Makefile sqlite3.pc
   947    948   
   948    949   #
   949    950   # Windows section
   950    951   #

Changes to Makefile.msc.

    25     25   USE_NATIVE_LIBPATHS = 0
    26     26   
    27     27   # Set this non-0 to compile binaries suitable for the WinRT environment.
    28     28   # This setting does not apply to any binaries that require Tcl to operate
    29     29   # properly (i.e. the text fixture, etc).
    30     30   #
    31     31   FOR_WINRT = 0
           32  +
           33  +# Set this non-0 to skip attempting to look for and/or link with the Tcl
           34  +# runtime library.
           35  +#
           36  +NO_TCL = 0
    32     37   
    33     38   # Set this to non-0 to create and use PDBs.
    34     39   #
    35     40   SYMBOLS = 1
    36     41   
    37     42   # Set this to one of the following values to enable various debugging
    38     43   # features.  Each level includes the debugging options from the previous
................................................................................
    71     76   # For example, to use the x86 compiler when cross-compiling for x64, a command
    72     77   # line similar to the following could be used (all on one line):
    73     78   #
    74     79   #     nmake /f Makefile.msc
    75     80   #           "NCC=""%VCINSTALLDIR%\bin\cl.exe"""
    76     81   #           USE_NATIVE_LIBPATHS=1
    77     82   #
    78         -!IFNDEF NCC
           83  +!IFDEF NCC
           84  +NCC = $(NCC:\\=\)
           85  +!ELSE
    79     86   NCC = $(CC)
    80     87   !ENDIF
    81     88   
    82     89   # Check for the MSVC runtime library path macro.  Othertise, this
    83     90   # value will default to the 'lib' directory underneath the MSVC
    84     91   # installation directory.
    85     92   #
    86     93   !IFNDEF NCRTLIBPATH
    87     94   NCRTLIBPATH = $(VCINSTALLDIR)\lib
    88     95   !ENDIF
           96  +
           97  +NCRTLIBPATH = $(NCRTLIBPATH:\\=\)
    89     98   
    90     99   # Check for the Platform SDK library path macro.  Othertise, this
    91    100   # value will default to the 'lib' directory underneath the Windows
    92    101   # SDK installation directory (the environment variable used appears
    93    102   # to be available when using Visual C++ 2008 or later via the
    94    103   # command line).
    95    104   #
    96    105   !IFNDEF NSDKLIBPATH
    97    106   NSDKLIBPATH = $(WINDOWSSDKDIR)\lib
    98    107   !ENDIF
          108  +
          109  +NSDKLIBPATH = $(NSDKLIBPATH:\\=\)
    99    110   
   100    111   # C compiler and options for use in building executables that
   101    112   # will run on the platform that is doing the build.
   102    113   #
   103    114   BCC = $(NCC) -W3
   104    115   
   105    116   # Check if the native library paths should be used when compiling
................................................................................
   119    130   # When compiling the library for use in the WinRT environment,
   120    131   # the following compile-time options must be used as well to
   121    132   # disable use of Win32 APIs that are not available and to enable
   122    133   # use of Win32 APIs that are specific to Windows 8 and/or WinRT.
   123    134   #
   124    135   !IF $(FOR_WINRT)!=0
   125    136   TCC = $(TCC) -DSQLITE_OS_WINRT=1
          137  +TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_PARTITION_APP
   126    138   !ENDIF
   127    139   
   128    140   # Also, we need to dynamically link to the correct MSVC runtime
   129    141   # when compiling for WinRT (e.g. debug or release) OR if the
   130    142   # USE_CRT_DLL option is set to force dynamically linking to the
   131    143   # MSVC runtime library.
   132    144   #
................................................................................
   340    352   
   341    353   # If either debugging or symbols are enabled, enable PDBs.
   342    354   !IF $(DEBUG)>0 || $(SYMBOLS)!=0
   343    355   LDFLAGS = /DEBUG
   344    356   !ENDIF
   345    357   
   346    358   # Start with the Tcl related linker options.
          359  +!IF $(NO_TCL)==0
   347    360   LTLIBPATHS = /LIBPATH:$(TCLLIBDIR)
   348    361   LTLIBS = $(LIBTCL)
          362  +!ENDIF
   349    363   
   350    364   # If ICU support is enabled, add the linker options for it.
   351    365   !IF $(USE_ICU)!=0
   352    366   LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ICULIBDIR)
   353    367   LTLIBS = $(LTLIBS) $(LIBICU)
   354    368   !ENDIF
   355    369   
................................................................................
  1108   1122   	-rmdir /Q/S tsrc
  1109   1123   	del /Q .target_source
  1110   1124   	del /Q tclsqlite3.exe
  1111   1125   	del /Q testfixture.exe testfixture.exp test.db
  1112   1126   	del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
  1113   1127   	del /Q sqlite3.c
  1114   1128   	del /Q sqlite3_analyzer.exe sqlite3_analyzer.exp sqlite3_analyzer.c
         1129  +	del /Q sqlite-output.vsix
  1115   1130   
  1116   1131   #
  1117   1132   # Windows section
  1118   1133   #
  1119   1134   dll: sqlite3.dll
  1120   1135   
  1121   1136   sqlite3.def: libsqlite3.lib

Changes to main.mk.

   612    612   	rm -f testloadext.dll libtestloadext.so
   613    613   	rm -f amalgamation-testfixture amalgamation-testfixture.exe
   614    614   	rm -f fts3-testfixture fts3-testfixture.exe
   615    615   	rm -f testfixture testfixture.exe
   616    616   	rm -f threadtest3 threadtest3.exe
   617    617   	rm -f sqlite3.c fts?amal.c tclsqlite3.c
   618    618   	rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
          619  +	rm -f sqlite-output.vsix

Changes to src/analyze.c.

   252    252     int mxSample;
   253    253     int n;
   254    254   
   255    255     UNUSED_PARAMETER(argc);
   256    256     nRow = (tRowcnt)sqlite3_value_int64(argv[0]);
   257    257     mxSample = sqlite3_value_int(argv[1]);
   258    258     n = sizeof(*p) + sizeof(p->a[0])*mxSample;
   259         -  p = sqlite3_malloc( n );
          259  +  p = sqlite3MallocZero( n );
   260    260     if( p==0 ){
   261    261       sqlite3_result_error_nomem(context);
   262    262       return;
   263    263     }
   264         -  memset(p, 0, n);
   265    264     p->a = (struct Stat3Sample*)&p[1];
   266    265     p->nRow = nRow;
   267    266     p->mxSample = mxSample;
   268    267     p->nPSample = p->nRow/(mxSample/3+1) + 1;
   269    268     sqlite3_randomness(sizeof(p->iPrn), &p->iPrn);
   270    269     sqlite3_result_blob(context, p, sizeof(p), sqlite3_free);
   271    270   }

Changes to src/backup.c.

   160    160       );
   161    161       p = 0;
   162    162     }else {
   163    163       /* Allocate space for a new sqlite3_backup object...
   164    164       ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
   165    165       ** call to sqlite3_backup_init() and is destroyed by a call to
   166    166       ** sqlite3_backup_finish(). */
   167         -    p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup));
          167  +    p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup));
   168    168       if( !p ){
   169    169         sqlite3Error(pDestDb, SQLITE_NOMEM, 0);
   170    170       }
   171    171     }
   172    172   
   173    173     /* If the allocation succeeded, populate the new object. */
   174    174     if( p ){
   175         -    memset(p, 0, sizeof(sqlite3_backup));
   176    175       p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb);
   177    176       p->pDest = findBtree(pDestDb, pDestDb, zDestDb);
   178    177       p->pDestDb = pDestDb;
   179    178       p->pSrcDb = pSrcDb;
   180    179       p->iNext = 1;
   181    180       p->isAttached = 0;
   182    181   

Changes to src/bitvec.c.

   336    336     int rc = -1;
   337    337     int i, nx, pc, op;
   338    338     void *pTmpSpace;
   339    339   
   340    340     /* Allocate the Bitvec to be tested and a linear array of
   341    341     ** bits to act as the reference */
   342    342     pBitvec = sqlite3BitvecCreate( sz );
   343         -  pV = sqlite3_malloc( (sz+7)/8 + 1 );
          343  +  pV = sqlite3MallocZero( (sz+7)/8 + 1 );
   344    344     pTmpSpace = sqlite3_malloc(BITVEC_SZ);
   345    345     if( pBitvec==0 || pV==0 || pTmpSpace==0  ) goto bitvec_end;
   346         -  memset(pV, 0, (sz+7)/8 + 1);
   347    346   
   348    347     /* NULL pBitvec tests */
   349    348     sqlite3BitvecSet(0, 1);
   350    349     sqlite3BitvecClear(0, 1, pTmpSpace);
   351    350   
   352    351     /* Run the program */
   353    352     pc = 0;

Changes to src/expr.c.

  1697   1697           ** table allocated and opened above.
  1698   1698           */
  1699   1699           SelectDest dest;
  1700   1700           ExprList *pEList;
  1701   1701   
  1702   1702           assert( !isRowid );
  1703   1703           sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
  1704         -        dest.affinity = (u8)affinity;
         1704  +        dest.affSdst = (u8)affinity;
  1705   1705           assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
  1706   1706           pExpr->x.pSelect->iLimit = 0;
  1707   1707           if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
  1708   1708             return 0;
  1709   1709           }
  1710   1710           pEList = pExpr->x.pSelect->pEList;
  1711   1711           if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){ 
................................................................................
  1790   1790         assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
  1791   1791   
  1792   1792         assert( ExprHasProperty(pExpr, EP_xIsSelect) );
  1793   1793         pSel = pExpr->x.pSelect;
  1794   1794         sqlite3SelectDestInit(&dest, 0, ++pParse->nMem);
  1795   1795         if( pExpr->op==TK_SELECT ){
  1796   1796           dest.eDest = SRT_Mem;
  1797         -        sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iParm);
         1797  +        sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm);
  1798   1798           VdbeComment((v, "Init subquery result"));
  1799   1799         }else{
  1800   1800           dest.eDest = SRT_Exists;
  1801         -        sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iParm);
         1801  +        sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
  1802   1802           VdbeComment((v, "Init EXISTS result"));
  1803   1803         }
  1804   1804         sqlite3ExprDelete(pParse->db, pSel->pLimit);
  1805   1805         pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
  1806   1806                                     &sqlite3IntTokens[1]);
  1807   1807         pSel->iLimit = 0;
  1808   1808         if( sqlite3Select(pParse, pSel, &dest) ){
  1809   1809           return 0;
  1810   1810         }
  1811         -      rReg = dest.iParm;
         1811  +      rReg = dest.iSDParm;
  1812   1812         ExprSetIrreducible(pExpr);
  1813   1813         break;
  1814   1814       }
  1815   1815     }
  1816   1816   
  1817   1817     if( testAddr>=0 ){
  1818   1818       sqlite3VdbeJumpHere(v, testAddr);

Changes to src/hash.c.

   112    112   #endif
   113    113   
   114    114     /* The inability to allocates space for a larger hash table is
   115    115     ** a performance hit but it is not a fatal error.  So mark the
   116    116     ** allocation as a benign.
   117    117     */
   118    118     sqlite3BeginBenignMalloc();
   119         -  new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) );
          119  +  new_ht = (struct _ht *)sqlite3MallocZero( new_size*sizeof(struct _ht) );
   120    120     sqlite3EndBenignMalloc();
   121    121   
   122    122     if( new_ht==0 ) return 0;
   123    123     sqlite3_free(pH->ht);
   124    124     pH->ht = new_ht;
   125    125     pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht);
   126         -  memset(new_ht, 0, new_size*sizeof(struct _ht));
   127    126     for(elem=pH->first, pH->first=0; elem; elem = next_elem){
   128    127       unsigned int h = strHash(elem->pKey, elem->nKey) % new_size;
   129    128       next_elem = elem->next;
   130    129       insertElement(pH, &new_ht[h], elem);
   131    130     }
   132    131     return 1;
   133    132   }

Changes to src/insert.c.

   593    593       int rc, j1;
   594    594   
   595    595       regEof = ++pParse->nMem;
   596    596       sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof);      /* EOF <- 0 */
   597    597       VdbeComment((v, "SELECT eof flag"));
   598    598       sqlite3SelectDestInit(&dest, SRT_Coroutine, ++pParse->nMem);
   599    599       addrSelect = sqlite3VdbeCurrentAddr(v)+2;
   600         -    sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iParm);
          600  +    sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iSDParm);
   601    601       j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
   602    602       VdbeComment((v, "Jump over SELECT coroutine"));
   603    603   
   604    604       /* Resolve the expressions in the SELECT statement and execute it. */
   605    605       rc = sqlite3Select(pParse, pSelect, &dest);
   606    606       assert( pParse->nErr==0 || rc );
   607    607       if( rc || NEVER(pParse->nErr) || db->mallocFailed ){
   608    608         goto insert_cleanup;
   609    609       }
   610    610       sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof);         /* EOF <- 1 */
   611         -    sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);   /* yield X */
          611  +    sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);   /* yield X */
   612    612       sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort);
   613    613       VdbeComment((v, "End of SELECT coroutine"));
   614    614       sqlite3VdbeJumpHere(v, j1);                          /* label B: */
   615    615   
   616         -    regFromSelect = dest.iMem;
          616  +    regFromSelect = dest.iSdst;
   617    617       assert( pSelect->pEList );
   618    618       nColumn = pSelect->pEList->nExpr;
   619         -    assert( dest.nMem==nColumn );
          619  +    assert( dest.nSdst==nColumn );
   620    620   
   621    621       /* Set useTempTable to TRUE if the result of the SELECT statement
   622    622       ** should be written into a temporary table (template 4).  Set to
   623    623       ** FALSE if each* row of the SELECT can be written directly into
   624    624       ** the destination table (template 3).
   625    625       **
   626    626       ** A temp table must be used if the table being updated is also one
................................................................................
   648    648         int addrTop;         /* Label "L" */
   649    649         int addrIf;          /* Address of jump to M */
   650    650   
   651    651         srcTab = pParse->nTab++;
   652    652         regRec = sqlite3GetTempReg(pParse);
   653    653         regTempRowid = sqlite3GetTempReg(pParse);
   654    654         sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
   655         -      addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);
          655  +      addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
   656    656         addrIf = sqlite3VdbeAddOp1(v, OP_If, regEof);
   657    657         sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
   658    658         sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
   659    659         sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
   660    660         sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
   661    661         sqlite3VdbeJumpHere(v, addrIf);
   662    662         sqlite3ReleaseTempReg(pParse, regRec);
................................................................................
   785    785       **
   786    786       **      C: yield X
   787    787       **         if EOF goto D
   788    788       **         insert the select result into <table> from R..R+n
   789    789       **         goto C
   790    790       **      D: ...
   791    791       */
   792         -    addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);
          792  +    addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
   793    793       addrInsTop = sqlite3VdbeAddOp1(v, OP_If, regEof);
   794    794     }
   795    795   
   796    796     /* Allocate registers for holding the rowid of the new row,
   797    797     ** the content of the new row, and the assemblied row record.
   798    798     */
   799    799     regRowid = regIns = pParse->nMem+1;

Changes to src/os.h.

    88     88   #if defined(_WIN32_WCE)
    89     89   # define SQLITE_OS_WINCE 1
    90     90   #else
    91     91   # define SQLITE_OS_WINCE 0
    92     92   #endif
    93     93   
    94     94   /*
    95         -** Determine if we are dealing with WindowsRT (Metro) as this has a different and
    96         -** incompatible API from win32.
           95  +** Determine if we are dealing with WinRT, which provides only a subset of
           96  +** the full Win32 API.
    97     97   */
    98     98   #if !defined(SQLITE_OS_WINRT)
    99     99   # define SQLITE_OS_WINRT 0
   100    100   #endif
   101    101   
   102    102   /*
   103    103   ** When compiled for WinCE or WinRT, there is no concept of the current

Changes to src/pcache1.c.

   392    392     nNew = p->nHash*2;
   393    393     if( nNew<256 ){
   394    394       nNew = 256;
   395    395     }
   396    396   
   397    397     pcache1LeaveMutex(p->pGroup);
   398    398     if( p->nHash ){ sqlite3BeginBenignMalloc(); }
   399         -  apNew = (PgHdr1 **)sqlite3_malloc(sizeof(PgHdr1 *)*nNew);
          399  +  apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew);
   400    400     if( p->nHash ){ sqlite3EndBenignMalloc(); }
   401    401     pcache1EnterMutex(p->pGroup);
   402    402     if( apNew ){
   403         -    memset(apNew, 0, sizeof(PgHdr1 *)*nNew);
   404    403       for(i=0; i<p->nHash; i++){
   405    404         PgHdr1 *pPage;
   406    405         PgHdr1 *pNext = p->apHash[i];
   407    406         while( (pPage = pNext)!=0 ){
   408    407           unsigned int h = pPage->iKey % nNew;
   409    408           pNext = pPage->pNext;
   410    409           pPage->pNext = apNew[h];
................................................................................
   580    579     int separateCache = sqlite3GlobalConfig.bCoreMutex>0;
   581    580   #endif
   582    581   
   583    582     assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 );
   584    583     assert( szExtra < 300 );
   585    584   
   586    585     sz = sizeof(PCache1) + sizeof(PGroup)*separateCache;
   587         -  pCache = (PCache1 *)sqlite3_malloc(sz);
          586  +  pCache = (PCache1 *)sqlite3MallocZero(sz);
   588    587     if( pCache ){
   589         -    memset(pCache, 0, sz);
   590    588       if( separateCache ){
   591    589         pGroup = (PGroup*)&pCache[1];
   592    590         pGroup->mxPinned = 10;
   593    591       }else{
   594    592         pGroup = &pcache1.grp;
   595    593       }
   596    594       pCache->pGroup = pGroup;

Changes to src/select.c.

    32     32   }
    33     33   
    34     34   /*
    35     35   ** Initialize a SelectDest structure.
    36     36   */
    37     37   void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){
    38     38     pDest->eDest = (u8)eDest;
    39         -  pDest->iParm = iParm;
    40         -  pDest->affinity = 0;
    41         -  pDest->iMem = 0;
    42         -  pDest->nMem = 0;
           39  +  pDest->iSDParm = iParm;
           40  +  pDest->affSdst = 0;
           41  +  pDest->iSdst = 0;
           42  +  pDest->nSdst = 0;
    43     43   }
    44     44   
    45     45   
    46     46   /*
    47     47   ** Allocate a new Select structure and return a pointer to that
    48     48   ** structure.
    49     49   */
................................................................................
   547    547     int iBreak              /* Jump here to break out of the inner loop */
   548    548   ){
   549    549     Vdbe *v = pParse->pVdbe;
   550    550     int i;
   551    551     int hasDistinct;        /* True if the DISTINCT keyword is present */
   552    552     int regResult;              /* Start of memory holding result set */
   553    553     int eDest = pDest->eDest;   /* How to dispose of results */
   554         -  int iParm = pDest->iParm;   /* First argument to disposal method */
          554  +  int iParm = pDest->iSDParm; /* First argument to disposal method */
   555    555     int nResultCol;             /* Number of result columns */
   556    556   
   557    557     assert( v );
   558    558     if( NEVER(v==0) ) return;
   559    559     assert( pEList!=0 );
   560    560     hasDistinct = distinct>=0;
   561    561     if( pOrderBy==0 && !hasDistinct ){
................................................................................
   565    565     /* Pull the requested columns.
   566    566     */
   567    567     if( nColumn>0 ){
   568    568       nResultCol = nColumn;
   569    569     }else{
   570    570       nResultCol = pEList->nExpr;
   571    571     }
   572         -  if( pDest->iMem==0 ){
   573         -    pDest->iMem = pParse->nMem+1;
   574         -    pDest->nMem = nResultCol;
          572  +  if( pDest->iSdst==0 ){
          573  +    pDest->iSdst = pParse->nMem+1;
          574  +    pDest->nSdst = nResultCol;
   575    575       pParse->nMem += nResultCol;
   576    576     }else{ 
   577         -    assert( pDest->nMem==nResultCol );
          577  +    assert( pDest->nSdst==nResultCol );
   578    578     }
   579         -  regResult = pDest->iMem;
          579  +  regResult = pDest->iSdst;
   580    580     if( nColumn>0 ){
   581    581       for(i=0; i<nColumn; i++){
   582    582         sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
   583    583       }
   584    584     }else if( eDest!=SRT_Exists ){
   585    585       /* If the destination is an EXISTS(...) expression, the actual
   586    586       ** values returned by the SELECT are not required.
................................................................................
   651    651   #ifndef SQLITE_OMIT_SUBQUERY
   652    652       /* If we are creating a set for an "expr IN (SELECT ...)" construct,
   653    653       ** then there should be a single item on the stack.  Write this
   654    654       ** item into the set table with bogus data.
   655    655       */
   656    656       case SRT_Set: {
   657    657         assert( nColumn==1 );
   658         -      p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity);
          658  +      p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst);
   659    659         if( pOrderBy ){
   660    660           /* At first glance you would think we could optimize out the
   661    661           ** ORDER BY in this case since the order of entries in the set
   662    662           ** does not matter.  But there might be a LIMIT clause, in which
   663    663           ** case the order does matter */
   664    664           pushOntoSorter(pParse, pOrderBy, p, regResult);
   665    665         }else{
................................................................................
   706    706         testcase( eDest==SRT_Output );
   707    707         if( pOrderBy ){
   708    708           int r1 = sqlite3GetTempReg(pParse);
   709    709           sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
   710    710           pushOntoSorter(pParse, pOrderBy, p, r1);
   711    711           sqlite3ReleaseTempReg(pParse, r1);
   712    712         }else if( eDest==SRT_Coroutine ){
   713         -        sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
          713  +        sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
   714    714         }else{
   715    715           sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn);
   716    716           sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn);
   717    717         }
   718    718         break;
   719    719       }
   720    720   
................................................................................
   886    886     int addrContinue = sqlite3VdbeMakeLabel(v);  /* Jump here for next cycle */
   887    887     int addr;
   888    888     int iTab;
   889    889     int pseudoTab = 0;
   890    890     ExprList *pOrderBy = p->pOrderBy;
   891    891   
   892    892     int eDest = pDest->eDest;
   893         -  int iParm = pDest->iParm;
          893  +  int iParm = pDest->iSDParm;
   894    894   
   895    895     int regRow;
   896    896     int regRowid;
   897    897   
   898    898     iTab = pOrderBy->iECursor;
   899    899     regRow = sqlite3GetTempReg(pParse);
   900    900     if( eDest==SRT_Output || eDest==SRT_Coroutine ){
................................................................................
   945    945   #endif
   946    946       default: {
   947    947         int i;
   948    948         assert( eDest==SRT_Output || eDest==SRT_Coroutine ); 
   949    949         testcase( eDest==SRT_Output );
   950    950         testcase( eDest==SRT_Coroutine );
   951    951         for(i=0; i<nColumn; i++){
   952         -        assert( regRow!=pDest->iMem+i );
   953         -        sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i);
          952  +        assert( regRow!=pDest->iSdst+i );
          953  +        sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iSdst+i);
   954    954           if( i==0 ){
   955    955             sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
   956    956           }
   957    957         }
   958    958         if( eDest==SRT_Output ){
   959         -        sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn);
   960         -        sqlite3ExprCacheAffinityChange(pParse, pDest->iMem, nColumn);
          959  +        sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn);
          960  +        sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn);
   961    961         }else{
   962         -        sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
          962  +        sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
   963    963         }
   964    964         break;
   965    965       }
   966    966     }
   967    967     sqlite3ReleaseTempReg(pParse, regRow);
   968    968     sqlite3ReleaseTempReg(pParse, regRowid);
   969    969   
................................................................................
  1606   1606     v = sqlite3GetVdbe(pParse);
  1607   1607     assert( v!=0 );  /* The VDBE already created by calling function */
  1608   1608   
  1609   1609     /* Create the destination temporary table if necessary
  1610   1610     */
  1611   1611     if( dest.eDest==SRT_EphemTab ){
  1612   1612       assert( p->pEList );
  1613         -    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, p->pEList->nExpr);
         1613  +    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr);
  1614   1614       sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
  1615   1615       dest.eDest = SRT_Table;
  1616   1616     }
  1617   1617   
  1618   1618     /* Make sure all SELECTs in the statement have the same number of elements
  1619   1619     ** in their result sets.
  1620   1620     */
................................................................................
  1692   1692           /* We can reuse a temporary table generated by a SELECT to our
  1693   1693           ** right.
  1694   1694           */
  1695   1695           assert( p->pRightmost!=p );  /* Can only happen for leftward elements
  1696   1696                                        ** of a 3-way or more compound */
  1697   1697           assert( p->pLimit==0 );      /* Not allowed on leftward elements */
  1698   1698           assert( p->pOffset==0 );     /* Not allowed on leftward elements */
  1699         -        unionTab = dest.iParm;
         1699  +        unionTab = dest.iSDParm;
  1700   1700         }else{
  1701   1701           /* We will need to create our own temporary table to hold the
  1702   1702           ** intermediate results.
  1703   1703           */
  1704   1704           unionTab = pParse->nTab++;
  1705   1705           assert( p->pOrderBy==0 );
  1706   1706           addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
................................................................................
  1749   1749         p->pOffset = pOffset;
  1750   1750         p->iLimit = 0;
  1751   1751         p->iOffset = 0;
  1752   1752   
  1753   1753         /* Convert the data in the temporary table into whatever form
  1754   1754         ** it is that we currently need.
  1755   1755         */
  1756         -      assert( unionTab==dest.iParm || dest.eDest!=priorOp );
         1756  +      assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
  1757   1757         if( dest.eDest!=priorOp ){
  1758   1758           int iCont, iBreak, iStart;
  1759   1759           assert( p->pEList );
  1760   1760           if( dest.eDest==SRT_Output ){
  1761   1761             Select *pFirst = p;
  1762   1762             while( pFirst->pPrior ) pFirst = pFirst->pPrior;
  1763   1763             generateColumnNames(pParse, 0, pFirst->pEList);
................................................................................
  1813   1813         assert( p->addrOpenEphm[1] == -1 );
  1814   1814         p->addrOpenEphm[1] = addr;
  1815   1815         p->pPrior = 0;
  1816   1816         pLimit = p->pLimit;
  1817   1817         p->pLimit = 0;
  1818   1818         pOffset = p->pOffset;
  1819   1819         p->pOffset = 0;
  1820         -      intersectdest.iParm = tab2;
         1820  +      intersectdest.iSDParm = tab2;
  1821   1821         explainSetInteger(iSub2, pParse->iNextSelectId);
  1822   1822         rc = sqlite3Select(pParse, p, &intersectdest);
  1823   1823         testcase( rc!=SQLITE_OK );
  1824   1824         pDelete = p->pPrior;
  1825   1825         p->pPrior = pPrior;
  1826   1826         if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
  1827   1827         sqlite3ExprDelete(db, p->pLimit);
................................................................................
  1907   1907           pLoop->addrOpenEphm[i] = -1;
  1908   1908         }
  1909   1909       }
  1910   1910       sqlite3DbFree(db, pKeyInfo);
  1911   1911     }
  1912   1912   
  1913   1913   multi_select_end:
  1914         -  pDest->iMem = dest.iMem;
  1915         -  pDest->nMem = dest.nMem;
         1914  +  pDest->iSdst = dest.iSdst;
         1915  +  pDest->nSdst = dest.nSdst;
  1916   1916     sqlite3SelectDelete(db, pDelete);
  1917   1917     return rc;
  1918   1918   }
  1919   1919   #endif /* SQLITE_OMIT_COMPOUND_SELECT */
  1920   1920   
  1921   1921   /*
  1922   1922   ** Code an output subroutine for a coroutine implementation of a
  1923   1923   ** SELECT statment.
  1924   1924   **
  1925         -** The data to be output is contained in pIn->iMem.  There are
  1926         -** pIn->nMem columns to be output.  pDest is where the output should
         1925  +** The data to be output is contained in pIn->iSdst.  There are
         1926  +** pIn->nSdst columns to be output.  pDest is where the output should
  1927   1927   ** be sent.
  1928   1928   **
  1929   1929   ** regReturn is the number of the register holding the subroutine
  1930   1930   ** return address.
  1931   1931   **
  1932   1932   ** If regPrev>0 then it is the first register in a vector that
  1933   1933   ** records the previous output.  mem[regPrev] is a flag that is false
................................................................................
  1957   1957     iContinue = sqlite3VdbeMakeLabel(v);
  1958   1958   
  1959   1959     /* Suppress duplicates for UNION, EXCEPT, and INTERSECT 
  1960   1960     */
  1961   1961     if( regPrev ){
  1962   1962       int j1, j2;
  1963   1963       j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev);
  1964         -    j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem,
         1964  +    j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
  1965   1965                                 (char*)pKeyInfo, p4type);
  1966   1966       sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
  1967   1967       sqlite3VdbeJumpHere(v, j1);
  1968         -    sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem);
         1968  +    sqlite3ExprCodeCopy(pParse, pIn->iSdst, regPrev+1, pIn->nSdst);
  1969   1969       sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
  1970   1970     }
  1971   1971     if( pParse->db->mallocFailed ) return 0;
  1972   1972   
  1973   1973     /* Suppress the the first OFFSET entries if there is an OFFSET clause
  1974   1974     */
  1975   1975     codeOffset(v, p, iContinue);
................................................................................
  1979   1979       */
  1980   1980       case SRT_Table:
  1981   1981       case SRT_EphemTab: {
  1982   1982         int r1 = sqlite3GetTempReg(pParse);
  1983   1983         int r2 = sqlite3GetTempReg(pParse);
  1984   1984         testcase( pDest->eDest==SRT_Table );
  1985   1985         testcase( pDest->eDest==SRT_EphemTab );
  1986         -      sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, pIn->nMem, r1);
  1987         -      sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iParm, r2);
  1988         -      sqlite3VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2);
         1986  +      sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1);
         1987  +      sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2);
         1988  +      sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2);
  1989   1989         sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
  1990   1990         sqlite3ReleaseTempReg(pParse, r2);
  1991   1991         sqlite3ReleaseTempReg(pParse, r1);
  1992   1992         break;
  1993   1993       }
  1994   1994   
  1995   1995   #ifndef SQLITE_OMIT_SUBQUERY
  1996   1996       /* If we are creating a set for an "expr IN (SELECT ...)" construct,
  1997   1997       ** then there should be a single item on the stack.  Write this
  1998   1998       ** item into the set table with bogus data.
  1999   1999       */
  2000   2000       case SRT_Set: {
  2001   2001         int r1;
  2002         -      assert( pIn->nMem==1 );
         2002  +      assert( pIn->nSdst==1 );
  2003   2003         p->affinity = 
  2004         -         sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity);
         2004  +         sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst);
  2005   2005         r1 = sqlite3GetTempReg(pParse);
  2006         -      sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iMem, 1, r1, &p->affinity, 1);
  2007         -      sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, 1);
  2008         -      sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iParm, r1);
         2006  +      sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &p->affinity, 1);
         2007  +      sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1);
         2008  +      sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1);
  2009   2009         sqlite3ReleaseTempReg(pParse, r1);
  2010   2010         break;
  2011   2011       }
  2012   2012   
  2013   2013   #if 0  /* Never occurs on an ORDER BY query */
  2014   2014       /* If any row exist in the result set, record that fact and abort.
  2015   2015       */
  2016   2016       case SRT_Exists: {
  2017         -      sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iParm);
         2017  +      sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iSDParm);
  2018   2018         /* The LIMIT clause will terminate the loop for us */
  2019   2019         break;
  2020   2020       }
  2021   2021   #endif
  2022   2022   
  2023   2023       /* If this is a scalar select that is part of an expression, then
  2024   2024       ** store the results in the appropriate memory cell and break out
  2025   2025       ** of the scan loop.
  2026   2026       */
  2027   2027       case SRT_Mem: {
  2028         -      assert( pIn->nMem==1 );
  2029         -      sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iParm, 1);
         2028  +      assert( pIn->nSdst==1 );
         2029  +      sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1);
  2030   2030         /* The LIMIT clause will jump out of the loop for us */
  2031   2031         break;
  2032   2032       }
  2033   2033   #endif /* #ifndef SQLITE_OMIT_SUBQUERY */
  2034   2034   
  2035   2035       /* The results are stored in a sequence of registers
  2036         -    ** starting at pDest->iMem.  Then the co-routine yields.
         2036  +    ** starting at pDest->iSdst.  Then the co-routine yields.
  2037   2037       */
  2038   2038       case SRT_Coroutine: {
  2039         -      if( pDest->iMem==0 ){
  2040         -        pDest->iMem = sqlite3GetTempRange(pParse, pIn->nMem);
  2041         -        pDest->nMem = pIn->nMem;
         2039  +      if( pDest->iSdst==0 ){
         2040  +        pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst);
         2041  +        pDest->nSdst = pIn->nSdst;
  2042   2042         }
  2043         -      sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iMem, pDest->nMem);
  2044         -      sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
         2043  +      sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst);
         2044  +      sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
  2045   2045         break;
  2046   2046       }
  2047   2047   
  2048   2048       /* If none of the above, then the result destination must be
  2049   2049       ** SRT_Output.  This routine is never called with any other
  2050   2050       ** destination other than the ones handled above or SRT_Output.
  2051   2051       **
  2052   2052       ** For SRT_Output, results are stored in a sequence of registers.  
  2053   2053       ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to
  2054   2054       ** return the next row of result.
  2055   2055       */
  2056   2056       default: {
  2057   2057         assert( pDest->eDest==SRT_Output );
  2058         -      sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iMem, pIn->nMem);
  2059         -      sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, pIn->nMem);
         2058  +      sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst);
         2059  +      sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst);
  2060   2060         break;
  2061   2061       }
  2062   2062     }
  2063   2063   
  2064   2064     /* Jump to the end of the loop if the LIMIT is reached.
  2065   2065     */
  2066   2066     if( p->iLimit ){
................................................................................
  2471   2471     sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
  2472   2472     sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB);
  2473   2473   
  2474   2474     /* Implement the main merge loop
  2475   2475     */
  2476   2476     sqlite3VdbeResolveLabel(v, labelCmpr);
  2477   2477     sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
  2478         -  sqlite3VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, nOrderBy,
         2478  +  sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
  2479   2479                            (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
  2480   2480     sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
  2481   2481   
  2482   2482     /* Release temporary registers
  2483   2483     */
  2484   2484     if( regPrev ){
  2485   2485       sqlite3ReleaseTempRange(pParse, regPrev, nOrderBy+1);
................................................................................
  3717   3717   **     pDest->eDest    Result
  3718   3718   **     ------------    -------------------------------------------
  3719   3719   **     SRT_Output      Generate a row of output (using the OP_ResultRow
  3720   3720   **                     opcode) for each row in the result set.
  3721   3721   **
  3722   3722   **     SRT_Mem         Only valid if the result is a single column.
  3723   3723   **                     Store the first column of the first result row
  3724         -**                     in register pDest->iParm then abandon the rest
         3724  +**                     in register pDest->iSDParm then abandon the rest
  3725   3725   **                     of the query.  This destination implies "LIMIT 1".
  3726   3726   **
  3727   3727   **     SRT_Set         The result must be a single column.  Store each
  3728         -**                     row of result as the key in table pDest->iParm. 
  3729         -**                     Apply the affinity pDest->affinity before storing
         3728  +**                     row of result as the key in table pDest->iSDParm. 
         3729  +**                     Apply the affinity pDest->affSdst before storing
  3730   3730   **                     results.  Used to implement "IN (SELECT ...)".
  3731   3731   **
  3732         -**     SRT_Union       Store results as a key in a temporary table pDest->iParm.
         3732  +**     SRT_Union       Store results as a key in a temporary table 
         3733  +**                     identified by pDest->iSDParm.
  3733   3734   **
  3734         -**     SRT_Except      Remove results from the temporary table pDest->iParm.
         3735  +**     SRT_Except      Remove results from the temporary table pDest->iSDParm.
  3735   3736   **
  3736         -**     SRT_Table       Store results in temporary table pDest->iParm.
         3737  +**     SRT_Table       Store results in temporary table pDest->iSDParm.
  3737   3738   **                     This is like SRT_EphemTab except that the table
  3738   3739   **                     is assumed to already be open.
  3739   3740   **
  3740         -**     SRT_EphemTab    Create an temporary table pDest->iParm and store
         3741  +**     SRT_EphemTab    Create an temporary table pDest->iSDParm and store
  3741   3742   **                     the result there. The cursor is left open after
  3742   3743   **                     returning.  This is like SRT_Table except that
  3743   3744   **                     this destination uses OP_OpenEphemeral to create
  3744   3745   **                     the table first.
  3745   3746   **
  3746   3747   **     SRT_Coroutine   Generate a co-routine that returns a new row of
  3747   3748   **                     results each time it is invoked.  The entry point
  3748         -**                     of the co-routine is stored in register pDest->iParm.
         3749  +**                     of the co-routine is stored in register pDest->iSDParm.
  3749   3750   **
  3750         -**     SRT_Exists      Store a 1 in memory cell pDest->iParm if the result
         3751  +**     SRT_Exists      Store a 1 in memory cell pDest->iSDParm if the result
  3751   3752   **                     set is not empty.
  3752   3753   **
  3753   3754   **     SRT_Discard     Throw the results away.  This is used by SELECT
  3754   3755   **                     statements within triggers whose only purpose is
  3755   3756   **                     the side-effects of functions.
  3756   3757   **
  3757   3758   ** This routine returns the number of errors.  If any errors are
................................................................................
  3987   3988     }else{
  3988   3989       addrSortIndex = -1;
  3989   3990     }
  3990   3991   
  3991   3992     /* If the output is destined for a temporary table, open that table.
  3992   3993     */
  3993   3994     if( pDest->eDest==SRT_EphemTab ){
  3994         -    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iParm, pEList->nExpr);
         3995  +    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr);
  3995   3996     }
  3996   3997   
  3997   3998     /* Set the limiter.
  3998   3999     */
  3999   4000     iEnd = sqlite3VdbeMakeLabel(v);
  4000   4001     p->nSelectRow = (double)LARGEST_INT64;
  4001   4002     computeLimitRegisters(pParse, p, iEnd);

Changes to src/sqlite.h.in.

  4148   4148   ** they return.  Hence, the calling function can deallocate or
  4149   4149   ** modify the text after they return without harm.
  4150   4150   ** ^The sqlite3_result_error_code() function changes the error code
  4151   4151   ** returned by SQLite as a result of an error in a function.  ^By default,
  4152   4152   ** the error code is SQLITE_ERROR.  ^A subsequent call to sqlite3_result_error()
  4153   4153   ** or sqlite3_result_error16() resets the error code to SQLITE_ERROR.
  4154   4154   **
  4155         -** ^The sqlite3_result_toobig() interface causes SQLite to throw an error
  4156         -** indicating that a string or BLOB is too long to represent.
         4155  +** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an
         4156  +** error indicating that a string or BLOB is too long to represent.
  4157   4157   **
  4158         -** ^The sqlite3_result_nomem() interface causes SQLite to throw an error
  4159         -** indicating that a memory allocation failed.
         4158  +** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an
         4159  +** error indicating that a memory allocation failed.
  4160   4160   **
  4161   4161   ** ^The sqlite3_result_int() interface sets the return value
  4162   4162   ** of the application-defined function to be the 32-bit signed integer
  4163   4163   ** value given in the 2nd argument.
  4164   4164   ** ^The sqlite3_result_int64() interface sets the return value
  4165   4165   ** of the application-defined function to be the 64-bit signed integer
  4166   4166   ** value given in the 2nd argument.

Changes to src/sqliteInt.h.

  2114   2114   /*
  2115   2115   ** A structure used to customize the behavior of sqlite3Select(). See
  2116   2116   ** comments above sqlite3Select() for details.
  2117   2117   */
  2118   2118   typedef struct SelectDest SelectDest;
  2119   2119   struct SelectDest {
  2120   2120     u8 eDest;         /* How to dispose of the results */
  2121         -  u8 affinity;      /* Affinity used when eDest==SRT_Set */
  2122         -  int iParm;        /* A parameter used by the eDest disposal method */
  2123         -  int iMem;         /* Base register where results are written */
  2124         -  int nMem;         /* Number of registers allocated */
         2121  +  u8 affSdst;       /* Affinity used when eDest==SRT_Set */
         2122  +  int iSDParm;      /* A parameter used by the eDest disposal method */
         2123  +  int iSdst;        /* Base register where results are written */
         2124  +  int nSdst;        /* Number of registers allocated */
  2125   2125   };
  2126   2126   
  2127   2127   /*
  2128   2128   ** During code generation of statements that do inserts into AUTOINCREMENT 
  2129   2129   ** tables, the following information is attached to the Table.u.autoInc.p
  2130   2130   ** pointer of each autoincrement table to record some side information that
  2131   2131   ** the code generator needs.  We have to keep per-table autoincrement

Changes to src/vdbeInt.h.

   427    427   # define sqlite3VdbeSorterRowkey(Y,Z)    SQLITE_OK
   428    428   # define sqlite3VdbeSorterRewind(X,Y,Z)  SQLITE_OK
   429    429   # define sqlite3VdbeSorterNext(X,Y,Z)    SQLITE_OK
   430    430   # define sqlite3VdbeSorterCompare(X,Y,Z) SQLITE_OK
   431    431   #else
   432    432   int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *);
   433    433   void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
   434         -int sqlite3VdbeSorterRowkey(VdbeCursor *, Mem *);
   435         -int sqlite3VdbeSorterNext(sqlite3 *, VdbeCursor *, int *);
   436         -int sqlite3VdbeSorterRewind(sqlite3 *, VdbeCursor *, int *);
   437         -int sqlite3VdbeSorterWrite(sqlite3 *, VdbeCursor *, Mem *);
   438         -int sqlite3VdbeSorterCompare(VdbeCursor *, Mem *, int *);
          434  +int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
          435  +int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
          436  +int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *);
          437  +int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *);
          438  +int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int *);
   439    439   #endif
   440    440   
   441    441   #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
   442    442     void sqlite3VdbeEnter(Vdbe*);
   443    443     void sqlite3VdbeLeave(Vdbe*);
   444    444   #else
   445    445   # define sqlite3VdbeEnter(X)

Changes to src/vdbesort.c.

   309    309   ** Initialize iterator pIter to scan through the PMA stored in file pFile
   310    310   ** starting at offset iStart and ending at offset iEof-1. This function 
   311    311   ** leaves the iterator pointing to the first key in the PMA (or EOF if the 
   312    312   ** PMA is empty).
   313    313   */
   314    314   static int vdbeSorterIterInit(
   315    315     sqlite3 *db,                    /* Database handle */
   316         -  VdbeSorter *pSorter,            /* Sorter object */
          316  +  const VdbeSorter *pSorter,      /* Sorter object */
   317    317     i64 iStart,                     /* Start offset in pFile */
   318    318     VdbeSorterIter *pIter,          /* Iterator to populate */
   319    319     i64 *pnByte                     /* IN/OUT: Increment this value by PMA size */
   320    320   ){
   321    321     int rc = SQLITE_OK;
   322    322     int nBuf;
   323    323   
................................................................................
   378    378   ** is true and key1 contains even a single NULL value, it is considered to
   379    379   ** be less than key2. Even if key2 also contains NULL values.
   380    380   **
   381    381   ** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace
   382    382   ** has been allocated and contains an unpacked record that is used as key2.
   383    383   */
   384    384   static void vdbeSorterCompare(
   385         -  VdbeCursor *pCsr,               /* Cursor object (for pKeyInfo) */
          385  +  const VdbeCursor *pCsr,         /* Cursor object (for pKeyInfo) */
   386    386     int bOmitRowid,                 /* Ignore rowid field at end of keys */
   387         -  void *pKey1, int nKey1,         /* Left side of comparison */
   388         -  void *pKey2, int nKey2,         /* Right side of comparison */
          387  +  const void *pKey1, int nKey1,   /* Left side of comparison */
          388  +  const void *pKey2, int nKey2,   /* Right side of comparison */
   389    389     int *pRes                       /* OUT: Result of comparison */
   390    390   ){
   391    391     KeyInfo *pKeyInfo = pCsr->pKeyInfo;
   392    392     VdbeSorter *pSorter = pCsr->pSorter;
   393    393     UnpackedRecord *r2 = pSorter->pUnpacked;
   394    394     int i;
   395    395   
................................................................................
   413    413   }
   414    414   
   415    415   /*
   416    416   ** This function is called to compare two iterator keys when merging 
   417    417   ** multiple b-tree segments. Parameter iOut is the index of the aTree[] 
   418    418   ** value to recalculate.
   419    419   */
   420         -static int vdbeSorterDoCompare(VdbeCursor *pCsr, int iOut){
          420  +static int vdbeSorterDoCompare(const VdbeCursor *pCsr, int iOut){
   421    421     VdbeSorter *pSorter = pCsr->pSorter;
   422    422     int i1;
   423    423     int i2;
   424    424     int iRes;
   425    425     VdbeSorterIter *p1;
   426    426     VdbeSorterIter *p2;
   427    427   
................................................................................
   539    539   }
   540    540   
   541    541   /*
   542    542   ** Merge the two sorted lists p1 and p2 into a single list.
   543    543   ** Set *ppOut to the head of the new list.
   544    544   */
   545    545   static void vdbeSorterMerge(
   546         -  VdbeCursor *pCsr,               /* For pKeyInfo */
          546  +  const VdbeCursor *pCsr,         /* For pKeyInfo */
   547    547     SorterRecord *p1,               /* First list to merge */
   548    548     SorterRecord *p2,               /* Second list to merge */
   549    549     SorterRecord **ppOut            /* OUT: Head of merged list */
   550    550   ){
   551    551     SorterRecord *pFinal = 0;
   552    552     SorterRecord **pp = &pFinal;
   553    553     void *pVal2 = p2 ? p2->pVal : 0;
................................................................................
   573    573   }
   574    574   
   575    575   /*
   576    576   ** Sort the linked list of records headed at pCsr->pRecord. Return SQLITE_OK
   577    577   ** if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if an error
   578    578   ** occurs.
   579    579   */
   580         -static int vdbeSorterSort(VdbeCursor *pCsr){
          580  +static int vdbeSorterSort(const VdbeCursor *pCsr){
   581    581     int i;
   582    582     SorterRecord **aSlot;
   583    583     SorterRecord *p;
   584    584     VdbeSorter *pSorter = pCsr->pSorter;
   585    585   
   586    586     aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
   587    587     if( !aSlot ){
................................................................................
   706    706   **     * A varint. This varint contains the total number of bytes of content
   707    707   **       in the PMA (not including the varint itself).
   708    708   **
   709    709   **     * One or more records packed end-to-end in order of ascending keys. 
   710    710   **       Each record consists of a varint followed by a blob of data (the 
   711    711   **       key). The varint is the number of bytes in the blob of data.
   712    712   */
   713         -static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){
          713  +static int vdbeSorterListToPMA(sqlite3 *db, const VdbeCursor *pCsr){
   714    714     int rc = SQLITE_OK;             /* Return code */
   715    715     int rc2;                        /* fileWriterFinish return code */
   716    716     VdbeSorter *pSorter = pCsr->pSorter;
   717    717     FileWriter writer;
   718    718   
   719    719     memset(&writer, 0, sizeof(FileWriter));
   720    720   
................................................................................
   764    764   }
   765    765   
   766    766   /*
   767    767   ** Add a record to the sorter.
   768    768   */
   769    769   int sqlite3VdbeSorterWrite(
   770    770     sqlite3 *db,                    /* Database handle */
   771         -  VdbeCursor *pCsr,               /* Sorter cursor */
          771  +  const VdbeCursor *pCsr,               /* Sorter cursor */
   772    772     Mem *pVal                       /* Memory cell containing record */
   773    773   ){
   774    774     VdbeSorter *pSorter = pCsr->pSorter;
   775    775     int rc = SQLITE_OK;             /* Return Code */
   776    776     SorterRecord *pNew;             /* New list element */
   777    777   
   778    778     assert( pSorter );
................................................................................
   816    816   }
   817    817   
   818    818   /*
   819    819   ** Helper function for sqlite3VdbeSorterRewind(). 
   820    820   */
   821    821   static int vdbeSorterInitMerge(
   822    822     sqlite3 *db,                    /* Database handle */
   823         -  VdbeCursor *pCsr,               /* Cursor handle for this sorter */
          823  +  const VdbeCursor *pCsr,         /* Cursor handle for this sorter */
   824    824     i64 *pnByte                     /* Sum of bytes in all opened PMAs */
   825    825   ){
   826    826     VdbeSorter *pSorter = pCsr->pSorter;
   827    827     int rc = SQLITE_OK;             /* Return code */
   828    828     int i;                          /* Used to iterator through aIter[] */
   829    829     i64 nByte = 0;                  /* Total bytes in all opened PMAs */
   830    830   
................................................................................
   846    846     return rc;
   847    847   }
   848    848   
   849    849   /*
   850    850   ** Once the sorter has been populated, this function is called to prepare
   851    851   ** for iterating through its contents in sorted order.
   852    852   */
   853         -int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){
          853  +int sqlite3VdbeSorterRewind(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
   854    854     VdbeSorter *pSorter = pCsr->pSorter;
   855    855     int rc;                         /* Return code */
   856    856     sqlite3_file *pTemp2 = 0;       /* Second temp file to use */
   857    857     i64 iWrite2 = 0;                /* Write offset for pTemp2 */
   858    858     int nIter;                      /* Number of iterators used */
   859    859     int nByte;                      /* Bytes of space required for aIter/aTree */
   860    860     int N = 2;                      /* Power of 2 >= nIter */
................................................................................
   964    964     *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0);
   965    965     return rc;
   966    966   }
   967    967   
   968    968   /*
   969    969   ** Advance to the next element in the sorter.
   970    970   */
   971         -int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){
          971  +int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
   972    972     VdbeSorter *pSorter = pCsr->pSorter;
   973    973     int rc;                         /* Return code */
   974    974   
   975    975     if( pSorter->aTree ){
   976    976       int iPrev = pSorter->aTree[1];/* Index of iterator to advance */
   977    977       int i;                        /* Index of aTree[] to recalculate */
   978    978   
................................................................................
   994    994   }
   995    995   
   996    996   /*
   997    997   ** Return a pointer to a buffer owned by the sorter that contains the 
   998    998   ** current key.
   999    999   */
  1000   1000   static void *vdbeSorterRowkey(
  1001         -  VdbeSorter *pSorter,            /* Sorter object */
         1001  +  const VdbeSorter *pSorter,      /* Sorter object */
  1002   1002     int *pnKey                      /* OUT: Size of current key in bytes */
  1003   1003   ){
  1004   1004     void *pKey;
  1005   1005     if( pSorter->aTree ){
  1006   1006       VdbeSorterIter *pIter;
  1007   1007       pIter = &pSorter->aIter[ pSorter->aTree[1] ];
  1008   1008       *pnKey = pIter->nKey;
................................................................................
  1013   1013     }
  1014   1014     return pKey;
  1015   1015   }
  1016   1016   
  1017   1017   /*
  1018   1018   ** Copy the current sorter key into the memory cell pOut.
  1019   1019   */
  1020         -int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){
         1020  +int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
  1021   1021     VdbeSorter *pSorter = pCsr->pSorter;
  1022   1022     void *pKey; int nKey;           /* Sorter key to copy into pOut */
  1023   1023   
  1024   1024     pKey = vdbeSorterRowkey(pSorter, &nKey);
  1025   1025     if( sqlite3VdbeMemGrow(pOut, nKey, 0) ){
  1026   1026       return SQLITE_NOMEM;
  1027   1027     }
................................................................................
  1039   1039   **
  1040   1040   ** If an error occurs, return an SQLite error code (i.e. SQLITE_NOMEM).
  1041   1041   ** Otherwise, set *pRes to a negative, zero or positive value if the
  1042   1042   ** key in pVal is smaller than, equal to or larger than the current sorter
  1043   1043   ** key.
  1044   1044   */
  1045   1045   int sqlite3VdbeSorterCompare(
  1046         -  VdbeCursor *pCsr,               /* Sorter cursor */
         1046  +  const VdbeCursor *pCsr,         /* Sorter cursor */
  1047   1047     Mem *pVal,                      /* Value to compare to current sorter key */
  1048   1048     int *pRes                       /* OUT: Result of comparison */
  1049   1049   ){
  1050   1050     VdbeSorter *pSorter = pCsr->pSorter;
  1051   1051     void *pKey; int nKey;           /* Sorter key to compare pVal with */
  1052   1052   
  1053   1053     pKey = vdbeSorterRowkey(pSorter, &nKey);
  1054   1054     vdbeSorterCompare(pCsr, 1, pVal->z, pVal->n, pKey, nKey, pRes);
  1055   1055     return SQLITE_OK;
  1056   1056   }
  1057   1057   
  1058   1058   #endif /* #ifndef SQLITE_OMIT_MERGE_SORT */

Changes to src/vdbetrace.c.

   165    165   /*
   166    166   ** Allocate a new Explain object
   167    167   */
   168    168   void sqlite3ExplainBegin(Vdbe *pVdbe){
   169    169     if( pVdbe ){
   170    170       Explain *p;
   171    171       sqlite3BeginBenignMalloc();
   172         -    p = sqlite3_malloc( sizeof(Explain) );
          172  +    p = (Explain *)sqlite3MallocZero( sizeof(Explain) );
   173    173       if( p ){
   174         -      memset(p, 0, sizeof(*p));
   175    174         p->pVdbe = pVdbe;
   176    175         sqlite3_free(pVdbe->pExplain);
   177    176         pVdbe->pExplain = p;
   178    177         sqlite3StrAccumInit(&p->str, p->zBase, sizeof(p->zBase),
   179    178                             SQLITE_MAX_LENGTH);
   180    179         p->str.useMalloc = 2;
   181    180       }else{

Added tool/build-all-msvc.bat.

            1  +@ECHO OFF
            2  +
            3  +::
            4  +:: build-all-msvc.bat --
            5  +::
            6  +:: Multi-Platform Build Tool for MSVC
            7  +::
            8  +
            9  +SETLOCAL
           10  +
           11  +REM SET __ECHO=ECHO
           12  +REM SET __ECHO2=ECHO
           13  +IF NOT DEFINED _AECHO (SET _AECHO=REM)
           14  +IF NOT DEFINED _CECHO (SET _CECHO=REM)
           15  +IF NOT DEFINED _VECHO (SET _VECHO=REM)
           16  +
           17  +%_AECHO% Running %0 %*
           18  +
           19  +REM SET DFLAGS=/L
           20  +
           21  +%_VECHO% DFlags = '%DFLAGS%'
           22  +
           23  +SET FFLAGS=/V /F /G /H /I /R /Y /Z
           24  +
           25  +%_VECHO% FFlags = '%FFLAGS%'
           26  +
           27  +SET ROOT=%~dp0\..
           28  +SET ROOT=%ROOT:\\=\%
           29  +
           30  +%_VECHO% Root = '%ROOT%'
           31  +
           32  +REM
           33  +REM NOTE: The first and only argument to this batch file should be the output
           34  +REM       directory where the platform-specific binary directories should be
           35  +REM       created.
           36  +REM
           37  +SET BINARYDIRECTORY=%1
           38  +
           39  +IF NOT DEFINED BINARYDIRECTORY (
           40  +  GOTO usage
           41  +)
           42  +
           43  +%_VECHO% BinaryDirectory = '%BINARYDIRECTORY%'
           44  +
           45  +SET DUMMY=%2
           46  +
           47  +IF DEFINED DUMMY (
           48  +  GOTO usage
           49  +)
           50  +
           51  +REM
           52  +REM NOTE: From this point, we need a clean error level.  Reset it now.
           53  +REM
           54  +CALL :fn_ResetErrorLevel
           55  +
           56  +REM
           57  +REM NOTE: Change the current directory to the root of the source tree, saving
           58  +REM       the current directory on the directory stack.
           59  +REM
           60  +%__ECHO2% PUSHD "%ROOT%"
           61  +
           62  +IF ERRORLEVEL 1 (
           63  +  ECHO Could not change directory to "%ROOT%".
           64  +  GOTO errors
           65  +)
           66  +
           67  +REM
           68  +REM NOTE: This batch file requires the ComSpec environment variable to be set,
           69  +REM       typically to something like "C:\Windows\System32\cmd.exe".
           70  +REM
           71  +IF NOT DEFINED ComSpec (
           72  +  ECHO The ComSpec environment variable must be defined.
           73  +  GOTO errors
           74  +)
           75  +
           76  +REM
           77  +REM NOTE: This batch file requires the VcInstallDir environment variable to be
           78  +REM       set.  Tyipcally, this means this batch file needs to be run from an
           79  +REM       MSVC command prompt.
           80  +REM
           81  +IF NOT DEFINED VCINSTALLDIR (
           82  +  ECHO The VCINSTALLDIR environment variable must be defined.
           83  +  GOTO errors
           84  +)
           85  +
           86  +REM
           87  +REM NOTE: If the list of platforms is not already set, use the default list.
           88  +REM
           89  +IF NOT DEFINED PLATFORMS (
           90  +  SET PLATFORMS=x86 x86_amd64 x86_arm
           91  +)
           92  +
           93  +%_VECHO% Platforms = '%PLATFORMS%'
           94  +
           95  +REM
           96  +REM NOTE: Setup environment variables to translate between the MSVC platform
           97  +REM       names and the names to be used for the platform-specific binary
           98  +REM       directories.
           99  +REM
          100  +SET x86_NAME=x86
          101  +SET x86_amd64_NAME=x64
          102  +SET x86_arm_NAME=ARM
          103  +
          104  +%_VECHO% x86_Name = '%x86_NAME%'
          105  +%_VECHO% x86_amd64_Name = '%x86_amd64_NAME%'
          106  +%_VECHO% x86_arm_Name = '%x86_arm_NAME%'
          107  +
          108  +REM
          109  +REM NOTE: Check for the external tools needed during the build process ^(i.e.
          110  +REM       those that do not get compiled as part of the build process itself^)
          111  +REM       along the PATH.
          112  +REM
          113  +FOR %%T IN (gawk.exe tclsh85.exe) DO (
          114  +  SET %%T_PATH=%%~dp$PATH:T
          115  +)
          116  +
          117  +REM
          118  +REM NOTE: Set the TOOLPATH variable to contain all the directories where the
          119  +REM       external tools were found in the search above.
          120  +REM
          121  +SET TOOLPATH=%gawk.exe_PATH%;%tclsh85.exe_PATH%
          122  +
          123  +%_VECHO% ToolPath = '%TOOLPATH%'
          124  +
          125  +REM
          126  +REM NOTE: Check for MSVC 2012 because the Windows SDK directory handling is
          127  +REM       slightly different for that version.
          128  +REM
          129  +IF "%VisualStudioVersion%" == "11.0" (
          130  +  SET SET_NSDKLIBPATH=1
          131  +) ELSE (
          132  +  CALL :fn_UnsetVariable SET_NSDKLIBPATH
          133  +)
          134  +
          135  +REM
          136  +REM NOTE: This is the outer loop.  There should be exactly one iteration per
          137  +REM       platform.
          138  +REM
          139  +FOR %%P IN (%PLATFORMS%) DO (
          140  +  REM
          141  +  REM NOTE: Using the MSVC platform name, lookup the simpler platform name to
          142  +  REM       be used for the name of the platform-specific binary directory via
          143  +  REM       the environment variables setup earlier.
          144  +  REM
          145  +  CALL :fn_SetVariable %%P_NAME PLATFORMNAME
          146  +
          147  +  REM
          148  +  REM NOTE: This is the inner loop.  There should be exactly one iteration.
          149  +  REM       This loop is necessary because the PlatformName environment
          150  +  REM       variable was set above and that value is needed by some of the
          151  +  REM       commands contained in the inner loop.  If these commands were
          152  +  REM       directly contained in the outer loop, the PlatformName environment
          153  +  REM       variable would be stuck with its initial empty value instead.
          154  +  REM
          155  +  FOR /F "tokens=2* delims==" %%D IN ('SET PLATFORMNAME') DO (
          156  +    REM
          157  +    REM NOTE: Attempt to clean the environment of all variables used by MSVC
          158  +    REM       and/or Visual Studio.  This block may need to be updated in the
          159  +    REM       future to account for additional environment variables.
          160  +    REM
          161  +    CALL :fn_UnsetVariable DevEnvDir
          162  +    CALL :fn_UnsetVariable ExtensionSdkDir
          163  +    CALL :fn_UnsetVariable Framework35Version
          164  +    CALL :fn_UnsetVariable FrameworkDir
          165  +    CALL :fn_UnsetVariable FrameworkDir32
          166  +    CALL :fn_UnsetVariable FrameworkVersion
          167  +    CALL :fn_UnsetVariable FrameworkVersion32
          168  +    CALL :fn_UnsetVariable FSHARPINSTALLDIR
          169  +    CALL :fn_UnsetVariable INCLUDE
          170  +    CALL :fn_UnsetVariable LIB
          171  +    CALL :fn_UnsetVariable LIBPATH
          172  +    CALL :fn_UnsetVariable Platform
          173  +    REM CALL :fn_UnsetVariable VCINSTALLDIR
          174  +    CALL :fn_UnsetVariable VSINSTALLDIR
          175  +    CALL :fn_UnsetVariable WindowsSdkDir
          176  +    CALL :fn_UnsetVariable WindowsSdkDir_35
          177  +    CALL :fn_UnsetVariable WindowsSdkDir_old
          178  +
          179  +    REM
          180  +    REM NOTE: Reset the PATH here to the absolute bare minimum required.
          181  +    REM
          182  +    SET PATH=%TOOLPATH%;%SystemRoot%\System32;%SystemRoot%
          183  +
          184  +    REM
          185  +    REM NOTE: Launch a nested command shell to perform the following steps:
          186  +    REM
          187  +    REM       1. Setup the MSVC environment for this platform using the
          188  +    REM          official batch file.
          189  +    REM
          190  +    REM       2. Make sure that no stale build output files are present.
          191  +    REM
          192  +    REM       3. Build the "sqlite3.dll" and "sqlite3.lib" binaries for this
          193  +    REM          platform.
          194  +    REM
          195  +    REM       4. Copy the "sqlite3.dll" and "sqlite3.lib" binaries for this
          196  +    REM          platform to the platform-specific directory beneath the
          197  +    REM          binary directory.
          198  +    REM
          199  +    "%ComSpec%" /C (
          200  +      REM
          201  +      REM NOTE: Attempt to setup the MSVC environment for this platform.
          202  +      REM
          203  +      %__ECHO% CALL "%VCINSTALLDIR%\vcvarsall.bat" %%P
          204  +
          205  +      IF ERRORLEVEL 1 (
          206  +        ECHO Failed to call "%VCINSTALLDIR%\vcvarsall.bat" for platform %%P.
          207  +        GOTO errors
          208  +      )
          209  +
          210  +      REM
          211  +      REM NOTE: If this batch file is not running in "what-if" mode, check to
          212  +      REM       be sure we were actually able to setup the MSVC environment as
          213  +      REM       current versions of their official batch file do not set the
          214  +      REM       exit code upon failure.
          215  +      REM
          216  +      IF NOT DEFINED __ECHO (
          217  +        IF NOT DEFINED WindowsSdkDir (
          218  +          ECHO Cannot build, Windows SDK not found for platform %%P.
          219  +          GOTO errors
          220  +        )
          221  +      )
          222  +
          223  +      REM
          224  +      REM NOTE: When using MSVC 2012, the native SDK path cannot simply use
          225  +      REM       the "lib" sub-directory beneath the location specified in the
          226  +      REM       WindowsSdkDir environment variable because that location does
          227  +      REM       not actually contain the necessary library files for x86.
          228  +      REM       This must be done for each iteration because it relies upon
          229  +      REM       the WindowsSdkDir environment variable being set by the batch
          230  +      REM       file used to setup the MSVC environment.
          231  +      REM
          232  +      IF DEFINED SET_NSDKLIBPATH (
          233  +        CALL :fn_SetVariable WindowsSdkDir NSDKLIBPATH
          234  +        CALL :fn_AppendVariable NSDKLIBPATH \lib\win8\um\x86
          235  +      )
          236  +
          237  +      REM
          238  +      REM NOTE: Unless prevented from doing so, invoke NMAKE with the MSVC
          239  +      REM       makefile to clean any stale build output from previous
          240  +      REM       iterations of this loop and/or previous runs of this batch
          241  +      REM       file, etc.
          242  +      REM
          243  +      IF NOT DEFINED NOCLEAN (
          244  +        %__ECHO% nmake -f Makefile.msc clean
          245  +
          246  +        IF ERRORLEVEL 1 (
          247  +          ECHO Failed to clean for platform %%P.
          248  +          GOTO errors
          249  +        )
          250  +      ) ELSE (
          251  +        REM
          252  +        REM NOTE: Even when the cleaning step has been disabled, we still need
          253  +        REM       to remove the build output for the files we are specifically
          254  +        REM       wanting to build for each platform.
          255  +        REM
          256  +        %__ECHO% DEL /Q sqlite3.dll sqlite3.lib sqlite3.pdb
          257  +      )
          258  +
          259  +      REM
          260  +      REM NOTE: Invoke NMAKE with the MSVC makefile to build the "sqlite3.dll"
          261  +      REM       binary.  The x86 compiler will be used to compile the native
          262  +      REM       command line tools needed during the build process itself.
          263  +      REM       Also, disable looking for and/or linking to the native Tcl
          264  +      REM       runtime library.
          265  +      REM
          266  +      %__ECHO% nmake -f Makefile.msc sqlite3.dll "NCC=""%VCINSTALLDIR%\bin\cl.exe""" USE_NATIVE_LIBPATHS=1 NO_TCL=1 %NMAKE_ARGS%
          267  +
          268  +      IF ERRORLEVEL 1 (
          269  +        ECHO Failed to build "sqlite3.dll" for platform %%P.
          270  +        GOTO errors
          271  +      )
          272  +
          273  +      REM
          274  +      REM NOTE: Copy the "sqlite3.dll" file to the platform-specific directory
          275  +      REM       beneath the binary directory.
          276  +      REM
          277  +      %__ECHO% XCOPY sqlite3.dll "%BINARYDIRECTORY%\%%D\" %FFLAGS% %DFLAGS%
          278  +
          279  +      IF ERRORLEVEL 1 (
          280  +        ECHO Failed to copy "sqlite3.dll" to "%BINARYDIRECTORY%\%%D\".
          281  +        GOTO errors
          282  +      )
          283  +
          284  +      REM
          285  +      REM NOTE: Copy the "sqlite3.lib" file to the platform-specific directory
          286  +      REM       beneath the binary directory.
          287  +      REM
          288  +      %__ECHO% XCOPY sqlite3.lib "%BINARYDIRECTORY%\%%D\" %FFLAGS% %DFLAGS%
          289  +
          290  +      IF ERRORLEVEL 1 (
          291  +        ECHO Failed to copy "sqlite3.lib" to "%BINARYDIRECTORY%\%%D\".
          292  +        GOTO errors
          293  +      )
          294  +
          295  +      REM
          296  +      REM NOTE: Copy the "sqlite3.pdb" file to the platform-specific directory
          297  +      REM       beneath the binary directory unless we are prevented from doing
          298  +      REM       so.
          299  +      REM
          300  +      IF NOT DEFINED NOSYMBOLS (
          301  +        %__ECHO% XCOPY sqlite3.pdb "%BINARYDIRECTORY%\%%D\" %FFLAGS% %DFLAGS%
          302  +
          303  +        IF ERRORLEVEL 1 (
          304  +          ECHO Failed to copy "sqlite3.pdb" to "%BINARYDIRECTORY%\%%D\".
          305  +          GOTO errors
          306  +        )
          307  +      )
          308  +    )
          309  +  )
          310  +
          311  +  REM
          312  +  REM NOTE: Handle any errors generated during the nested command shell.
          313  +  REM
          314  +  IF ERRORLEVEL 1 (
          315  +    GOTO errors
          316  +  )
          317  +)
          318  +
          319  +REM
          320  +REM NOTE: Restore the saved current directory from the directory stack.
          321  +REM
          322  +%__ECHO2% POPD
          323  +
          324  +IF ERRORLEVEL 1 (
          325  +  ECHO Could not restore directory.
          326  +  GOTO errors
          327  +)
          328  +
          329  +REM
          330  +REM NOTE: If we get to this point, we have succeeded.
          331  +REM
          332  +GOTO no_errors
          333  +
          334  +:fn_ResetErrorLevel
          335  +  VERIFY > NUL
          336  +  GOTO :EOF
          337  +
          338  +:fn_SetErrorLevel
          339  +  VERIFY MAYBE 2> NUL
          340  +  GOTO :EOF
          341  +
          342  +:fn_SetVariable
          343  +  SETLOCAL
          344  +  IF NOT DEFINED %1 GOTO :EOF
          345  +  IF "%2" == "" GOTO :EOF
          346  +  SET __ECHO_CMD=ECHO %%%1%%
          347  +  FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO (
          348  +    SET VALUE=%%V
          349  +  )
          350  +  ENDLOCAL && SET %2=%VALUE%
          351  +  GOTO :EOF
          352  +
          353  +:fn_UnsetVariable
          354  +  IF NOT "%1" == "" (
          355  +    SET %1=
          356  +    CALL :fn_ResetErrorLevel
          357  +  )
          358  +  GOTO :EOF
          359  +
          360  +:fn_AppendVariable
          361  +  SET __ECHO_CMD=ECHO %%%1%%
          362  +  IF DEFINED %1 (
          363  +    FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO (
          364  +      SET %1=%%V%~2
          365  +    )
          366  +  ) ELSE (
          367  +    SET %1=%~2
          368  +  )
          369  +  SET __ECHO_CMD=
          370  +  CALL :fn_ResetErrorLevel
          371  +  GOTO :EOF
          372  +
          373  +:usage
          374  +  ECHO.
          375  +  ECHO Usage: %~nx0 ^<binaryDirectory^>
          376  +  ECHO.
          377  +  GOTO errors
          378  +
          379  +:errors
          380  +  CALL :fn_SetErrorLevel
          381  +  ENDLOCAL
          382  +  ECHO.
          383  +  ECHO Failure, errors were encountered.
          384  +  GOTO end_of_file
          385  +
          386  +:no_errors
          387  +  CALL :fn_ResetErrorLevel
          388  +  ENDLOCAL
          389  +  ECHO.
          390  +  ECHO Success, no errors were encountered.
          391  +  GOTO end_of_file
          392  +
          393  +:end_of_file
          394  +%__ECHO% EXIT /B %ERRORLEVEL%

Added tool/mkvsix.tcl.

            1  +#!/usr/bin/tclsh
            2  +#
            3  +# This script is used to generate a VSIX (Visual Studio Extension) file for
            4  +# SQLite usable by Visual Studio.
            5  +
            6  +proc fail { {error ""} {usage false} } {
            7  +  if {[string length $error] > 0} then {
            8  +    puts stdout $error
            9  +    if {!$usage} then {exit 1}
           10  +  }
           11  +
           12  +  puts stdout "usage:\
           13  +[file tail [info nameofexecutable]]\
           14  +[file tail [info script]] <binaryDirectory> \[sourceDirectory\]"
           15  +
           16  +  exit 1
           17  +}
           18  +
           19  +proc getEnvironmentVariable { name } {
           20  +  #
           21  +  # NOTE: Returns the value of the specified environment variable or an empty
           22  +  #       string for environment variables that do not exist in the current
           23  +  #       process environment.
           24  +  #
           25  +  return [expr {[info exists ::env($name)] ? $::env($name) : ""}]
           26  +}
           27  +
           28  +proc getTemporaryPath {} {
           29  +  #
           30  +  # NOTE: Returns the normalized path to the first temporary directory found
           31  +  #       in the typical set of environment variables used for that purpose
           32  +  #       or an empty string to signal a failure to locate such a directory.
           33  +  #
           34  +  set names [list]
           35  +
           36  +  foreach name [list TEMP TMP] {
           37  +    lappend names [string toupper $name] [string tolower $name] \
           38  +        [string totitle $name]
           39  +  }
           40  +
           41  +  foreach name $names {
           42  +    set value [getEnvironmentVariable $name]
           43  +
           44  +    if {[string length $value] > 0} then {
           45  +      return [file normalize $value]
           46  +    }
           47  +  }
           48  +
           49  +  return ""
           50  +}
           51  +
           52  +proc appendArgs { args } {
           53  +  #
           54  +  # NOTE: Returns all passed arguments joined together as a single string with
           55  +  #       no intervening spaces between arguments.
           56  +  #
           57  +  eval append result $args
           58  +}
           59  +
           60  +proc readFile { fileName } {
           61  +  #
           62  +  # NOTE: Reads and returns the entire contents of the specified file, which
           63  +  #       may contain binary data.
           64  +  #
           65  +  set file_id [open $fileName RDONLY]
           66  +  fconfigure $file_id -encoding binary -translation binary
           67  +  set result [read $file_id]
           68  +  close $file_id
           69  +  return $result
           70  +}
           71  +
           72  +proc writeFile { fileName data } {
           73  +  #
           74  +  # NOTE: Writes the entire contents of the specified file, which may contain
           75  +  #       binary data.
           76  +  #
           77  +  set file_id [open $fileName {WRONLY CREAT TRUNC}]
           78  +  fconfigure $file_id -encoding binary -translation binary
           79  +  puts -nonewline $file_id $data
           80  +  close $file_id
           81  +  return ""
           82  +}
           83  +
           84  +proc substFile { fileName } {
           85  +  #
           86  +  # NOTE: Performs all Tcl command, variable, and backslash substitutions in
           87  +  #       the specified file and then re-writes the contents of that same file
           88  +  #       with the substituted data.
           89  +  #
           90  +  return [writeFile $fileName [uplevel 1 [list subst [readFile $fileName]]]]
           91  +}
           92  +
           93  +proc replacePlatform { fileName platformName } {
           94  +  #
           95  +  # NOTE: Returns the specified file name containing the platform name instead
           96  +  #       of platform placeholder tokens.
           97  +  #
           98  +  return [string map [list <platform> $platformName] $fileName]
           99  +}
          100  +
          101  +set script [file normalize [info script]]
          102  +
          103  +if {[string length $script] == 0} then {
          104  +  fail "script file currently being evaluated is unknown" true
          105  +}
          106  +
          107  +set path [file dirname $script]
          108  +set rootName [file rootname [file tail $script]]
          109  +
          110  +###############################################################################
          111  +
          112  +#
          113  +# NOTE: Process and verify all the command line arguments.
          114  +#
          115  +set argc [llength $argv]
          116  +if {$argc != 1 && $argc != 2} then {fail}
          117  +
          118  +set binaryDirectory [lindex $argv 0]
          119  +
          120  +if {[string length $binaryDirectory] == 0} then {
          121  +  fail "invalid binary directory"
          122  +}
          123  +
          124  +if {![file exists $binaryDirectory] || \
          125  +    ![file isdirectory $binaryDirectory]} then {
          126  +  fail "binary directory does not exist"
          127  +}
          128  +
          129  +if {$argc == 2} then {
          130  +  set sourceDirectory [lindex $argv 1]
          131  +} else {
          132  +  #
          133  +  # NOTE: Assume that the source directory is the parent directory of the one
          134  +  #       that contains this script file.
          135  +  #
          136  +  set sourceDirectory [file dirname $path]
          137  +}
          138  +
          139  +if {[string length $sourceDirectory] == 0} then {
          140  +  fail "invalid source directory"
          141  +}
          142  +
          143  +if {![file exists $sourceDirectory] || \
          144  +    ![file isdirectory $sourceDirectory]} then {
          145  +  fail "source directory does not exist"
          146  +}
          147  +
          148  +###############################################################################
          149  +
          150  +#
          151  +# NOTE: Evaluate the user-specific customizations file, if it exists.
          152  +#
          153  +set userFile [file join $path [appendArgs \
          154  +    $rootName . $tcl_platform(user) .tcl]]
          155  +
          156  +if {[file exists $userFile] && \
          157  +    [file isfile $userFile]} then {
          158  +  source $userFile
          159  +}
          160  +
          161  +###############################################################################
          162  +
          163  +set templateFile [file join $path win sqlite.vsix]
          164  +
          165  +if {![file exists $templateFile] || \
          166  +    ![file isfile $templateFile]} then {
          167  +  fail [appendArgs "template file \"" $templateFile "\" does not exist"]
          168  +}
          169  +
          170  +set currentDirectory [pwd]
          171  +set outputFile [file join $currentDirectory sqlite-output.vsix]
          172  +
          173  +if {[file exists $outputFile]} then {
          174  +  fail [appendArgs "output file \"" $outputFile "\" already exists"]
          175  +}
          176  +
          177  +###############################################################################
          178  +
          179  +#
          180  +# NOTE: Make sure that a valid temporary directory exists.
          181  +#
          182  +set temporaryDirectory [getTemporaryPath]
          183  +
          184  +if {[string length $temporaryDirectory] == 0 || \
          185  +    ![file exists $temporaryDirectory] || \
          186  +    ![file isdirectory $temporaryDirectory]} then {
          187  +  fail "cannot locate a usable temporary directory"
          188  +}
          189  +
          190  +#
          191  +# NOTE: Setup the staging directory to have a unique name inside of the
          192  +#       configured temporary directory.
          193  +#
          194  +set stagingDirectory [file normalize [file join $temporaryDirectory \
          195  +    [appendArgs $rootName . [pid]]]]
          196  +
          197  +###############################################################################
          198  +
          199  +#
          200  +# NOTE: Configure the external zipping tool.  First, see if it has already
          201  +#       been pre-configured.  If not, try to query it from the environment.
          202  +#       Finally, fallback on the default of simply "zip", which will then
          203  +#       be assumed to exist somewhere along the PATH.
          204  +#
          205  +if {![info exists zip]} then {
          206  +  if {[info exists env(ZipTool)]} then {
          207  +    set zip $env(ZipTool)
          208  +  }
          209  +  if {![info exists zip] || ![file exists $zip]} then {
          210  +    set zip zip
          211  +  }
          212  +}
          213  +
          214  +#
          215  +# NOTE: Configure the external unzipping tool.  First, see if it has already
          216  +#       been pre-configured.  If not, try to query it from the environment.
          217  +#       Finally, fallback on the default of simply "unzip", which will then
          218  +#       be assumed to exist somewhere along the PATH.
          219  +#
          220  +if {![info exists unzip]} then {
          221  +  if {[info exists env(UnZipTool)]} then {
          222  +    set unzip $env(UnZipTool)
          223  +  }
          224  +  if {![info exists unzip] || ![file exists $unzip]} then {
          225  +    set unzip unzip
          226  +  }
          227  +}
          228  +
          229  +###############################################################################
          230  +
          231  +#
          232  +# NOTE: Attempt to extract the SQLite version from the "sqlite3.h" header file
          233  +#       in the source directory.  This script assumes that the header file has
          234  +#       already been generated by the build process.
          235  +#
          236  +set pattern {^#define\s+SQLITE_VERSION\s+"(.*)"$}
          237  +set data [readFile [file join $sourceDirectory sqlite3.h]]
          238  +
          239  +if {![regexp -line -- $pattern $data dummy version]} then {
          240  +  fail [appendArgs "cannot locate SQLITE_VERSION value in \"" \
          241  +      [file join $sourceDirectory sqlite3.h] \"]
          242  +}
          243  +
          244  +###############################################################################
          245  +
          246  +#
          247  +# NOTE: Setup the master file list data, including the necessary flags.
          248  +#
          249  +if {![info exists fileNames(source)]} then {
          250  +  set fileNames(source) [list "" "" "" \
          251  +      [file join $sourceDirectory sqlite3.h] \
          252  +      [file join $binaryDirectory <platform> sqlite3.lib] \
          253  +      [file join $binaryDirectory <platform> sqlite3.dll]]
          254  +
          255  +  if {![info exists no(symbols)]} then {
          256  +    lappend fileNames(source) \
          257  +        [file join $binaryDirectory <platform> sqlite3.pdb]
          258  +  }
          259  +}
          260  +
          261  +if {![info exists fileNames(destination)]} then {
          262  +  set fileNames(destination) [list \
          263  +      [file join $stagingDirectory extension.vsixmanifest] \
          264  +      [file join $stagingDirectory SDKManifest.xml] \
          265  +      [file join $stagingDirectory DesignTime CommonConfiguration \
          266  +          <platform> SQLite.WinRT.props] \
          267  +      [file join $stagingDirectory DesignTime CommonConfiguration \
          268  +          <platform> sqlite3.h] \
          269  +      [file join $stagingDirectory DesignTime CommonConfiguration \
          270  +          <platform> sqlite3.lib] \
          271  +      [file join $stagingDirectory Redist CommonConfiguration \
          272  +          <platform> sqlite3.dll]]
          273  +
          274  +  if {![info exists no(symbols)]} then {
          275  +    lappend fileNames(destination) \
          276  +        [file join $stagingDirectory Redist CommonConfiguration \
          277  +            <platform> sqlite3.pdb]
          278  +  }
          279  +}
          280  +
          281  +if {![info exists fileNames(neutral)]} then {
          282  +  set fileNames(neutral) [list 1 1 1 1 0 0]
          283  +
          284  +  if {![info exists no(symbols)]} then {
          285  +    lappend fileNames(neutral) 0
          286  +  }
          287  +}
          288  +
          289  +if {![info exists fileNames(subst)]} then {
          290  +  set fileNames(subst) [list 1 1 1 0 0 0]
          291  +
          292  +  if {![info exists no(symbols)]} then {
          293  +    lappend fileNames(subst) 0
          294  +  }
          295  +}
          296  +
          297  +###############################################################################
          298  +
          299  +#
          300  +# NOTE: Setup the list of platforms supported by this script.
          301  +#
          302  +if {![info exists platformNames]} then {
          303  +  set platformNames [list x86 x64 ARM]
          304  +}
          305  +
          306  +###############################################################################
          307  +
          308  +#
          309  +# NOTE: Make sure the staging directory exists, creating it if necessary.
          310  +#
          311  +file mkdir $stagingDirectory
          312  +
          313  +#
          314  +# NOTE: Build the Tcl command used to extract the template package to the
          315  +#       staging directory.
          316  +#
          317  +set extractCommand [list exec -- $unzip $templateFile -d $stagingDirectory]
          318  +
          319  +#
          320  +# NOTE: Extract the template package to the staging directory.
          321  +#
          322  +eval $extractCommand
          323  +
          324  +###############################################################################
          325  +
          326  +#
          327  +# NOTE: Process each file in the master file list.  There are actually four
          328  +#       parallel lists that contain the source file names, destination file
          329  +#       names, the platform-neutral flags, and the use-subst flags.  When the
          330  +#       platform-neutral flag is non-zero, the file is not platform-specific.
          331  +#       When the use-subst flag is non-zero, the file is considered to be a
          332  +#       text file that may contain Tcl variable and/or command replacements,
          333  +#       to be dynamically replaced during processing.  If the source file name
          334  +#       is an empty string, then the destination file name will be assumed to
          335  +#       already exist in the staging directory and will not be copied; however,
          336  +#       dynamic replacements may still be performed on the destination file
          337  +#       prior to the package being re-zipped.
          338  +#
          339  +foreach sourceFileName $fileNames(source) \
          340  +    destinationFileName $fileNames(destination) \
          341  +    isNeutral $fileNames(neutral) useSubst $fileNames(subst) {
          342  +  #
          343  +  # NOTE: If the current file is platform-neutral, then only one platform will
          344  +  #       be processed for it, namely "neutral"; otherwise, each supported
          345  +  #       platform will be processed for it individually.
          346  +  #
          347  +  foreach platformName [expr {$isNeutral ? [list neutral] : $platformNames}] {
          348  +    #
          349  +    # NOTE: Use the actual platform name in the destination file name.
          350  +    #
          351  +    set newDestinationFileName [replacePlatform $destinationFileName \
          352  +        $platformName]
          353  +
          354  +    #
          355  +    # NOTE: Does the source file need to be copied to the destination file?
          356  +    #
          357  +    if {[string length $sourceFileName] > 0} then {
          358  +      #
          359  +      # NOTE: First, make sure the destination directory exists.
          360  +      #
          361  +      file mkdir [file dirname $newDestinationFileName]
          362  +
          363  +      #
          364  +      # NOTE: Then, copy the source file to the destination file verbatim.
          365  +      #
          366  +      file copy [replacePlatform $sourceFileName $platformName] \
          367  +          $newDestinationFileName
          368  +    }
          369  +
          370  +    #
          371  +    # NOTE: Does the destination file contain dynamic replacements that must
          372  +    #       be processed now?
          373  +    #
          374  +    if {$useSubst} then {
          375  +      #
          376  +      # NOTE: Perform any dynamic replacements contained in the destination
          377  +      #       file and then re-write it in-place.
          378  +      #
          379  +      substFile $newDestinationFileName
          380  +    }
          381  +  }
          382  +}
          383  +
          384  +###############################################################################
          385  +
          386  +#
          387  +# NOTE: Change the current directory to the staging directory so that the
          388  +#       external archive building tool can pickup the necessary files using
          389  +#       relative paths.
          390  +#
          391  +cd $stagingDirectory
          392  +
          393  +#
          394  +# NOTE: Build the Tcl command used to archive the final package in the
          395  +#       output directory.
          396  +#
          397  +set archiveCommand [list exec -- $zip -r $outputFile *]
          398  +
          399  +#
          400  +# NOTE: Build the final package archive in the output directory.
          401  +#
          402  +eval $archiveCommand
          403  +
          404  +#
          405  +# NOTE: Change back to the previously saved current directory.
          406  +#
          407  +cd $currentDirectory
          408  +
          409  +#
          410  +# NOTE: Cleanup the temporary staging directory.
          411  +#
          412  +file delete -force $stagingDirectory
          413  +
          414  +###############################################################################
          415  +
          416  +#
          417  +# NOTE: Success, emit the fully qualified path of the generated VSIX file.
          418  +#
          419  +puts stdout $outputFile

Added tool/win/sqlite.vsix.

cannot compute difference between binary files