/ Check-in [415c448d]
Login

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

Overview
Comment:Merge changes through release 3.7.2 into the apple-osx branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA1: 415c448dc45a297bd1b0bbce25c4572eeab286f0
User & Date: drh 2010-08-24 01:08:11
References
2010-09-09
23:31
The merge for check-in [415c448dc4] did not do exactly write, resulting in a subtle bug in the SQLITE_FCNTL_SIZE_HINT logic. This check-in is the fix. check-in: badaaa18 user: drh tags: apple-osx
Context
2010-08-24
01:51
Merge in the R-tree fix from the trunk. check-in: 02ee0bd5 user: drh tags: apple-osx
01:08
Merge changes through release 3.7.2 into the apple-osx branch. check-in: 415c448d user: drh tags: apple-osx
00:40
Version 3.7.2 check-in: 42537b60 user: drh tags: trunk, release, version-3.7.2
2010-08-18
00:24
Merge the 3.7.1 pre-release snapshot changes as of 2010-08-18 into the apple-osx branch. check-in: 866e9286 user: drh tags: apple-osx
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   758    758   tclsqlite.lo:	$(TOP)/src/tclsqlite.c $(HDR)
   759    759   	$(LTCOMPILE) -DUSE_TCL_STUBS=1 -c $(TOP)/src/tclsqlite.c
   760    760   
   761    761   tclsqlite-shell.lo:	$(TOP)/src/tclsqlite.c $(HDR)
   762    762   	$(LTCOMPILE) -DTCLSH=1 -o $@ -c $(TOP)/src/tclsqlite.c
   763    763   
   764    764   tclsqlite-stubs.lo:	$(TOP)/src/tclsqlite.c $(HDR)
   765         -	$(LTCOMPILE) -DTCL_USE_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c
          765  +	$(LTCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c
   766    766   
   767    767   tclsqlite3$(TEXE):	tclsqlite-shell.lo libsqlite3.la
   768    768   	$(LTLINK) -o $@ tclsqlite-shell.lo \
   769    769   		 libsqlite3.la $(LIBTCL)
   770    770   
   771    771   # Rules to build opcodes.c and opcodes.h
   772    772   #

Changes to VERSION.

     1         -3.7.1
            1  +3.7.2

Changes to configure.

     1      1   #! /bin/sh
     2      2   # Guess values for system-dependent variables and create Makefiles.
     3         -# Generated by GNU Autoconf 2.62 for sqlite >>>>>>> BEGIN MERGE CONFLICT3.7.1============================3.7.0.1<<<<<<< END MERGE CONFLICT.
            3  +# Generated by GNU Autoconf 2.62 for sqlite 3.7.2.
     4      4   #
     5      5   # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
     6      6   # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
     7      7   # This configure script is free software; the Free Software Foundation
     8      8   # gives unlimited permission to copy, distribute and modify it.
     9      9   ## --------------------- ##
    10     10   ## M4sh Initialization.  ##
................................................................................
   739    739   MFLAGS=
   740    740   MAKEFLAGS=
   741    741   SHELL=${CONFIG_SHELL-/bin/sh}
   742    742   
   743    743   # Identity of this package.
   744    744   PACKAGE_NAME='sqlite'
   745    745   PACKAGE_TARNAME='sqlite'
   746         -PACKAGE_VERSION='>>>>>>> BEGIN MERGE CONFLICT3.7.1============================3.7.0.1<<<<<<< END MERGE CONFLICT'
   747         -PACKAGE_STRING='sqlite >>>>>>> BEGIN MERGE CONFLICT3.7.1============================3.7.0.1<<<<<<< END MERGE CONFLICT'
          746  +PACKAGE_VERSION='3.7.2'
          747  +PACKAGE_STRING='sqlite 3.7.2'
   748    748   PACKAGE_BUGREPORT=''
   749    749   
   750    750   # Factoring default headers for most tests.
   751    751   ac_includes_default="\
   752    752   #include <stdio.h>
   753    753   #ifdef HAVE_SYS_TYPES_H
   754    754   # include <sys/types.h>
................................................................................
  1483   1483   #
  1484   1484   # Report the --help message.
  1485   1485   #
  1486   1486   if test "$ac_init_help" = "long"; then
  1487   1487     # Omit some internal or obsolete options to make the list less imposing.
  1488   1488     # This message is too long to be a string in the A/UX 3.1 sh.
  1489   1489     cat <<_ACEOF
  1490         -\`configure' configures sqlite >>>>>>> BEGIN MERGE CONFLICT3.7.1============================3.7.0.1<<<<<<< END MERGE CONFLICT to adapt to many kinds of systems.
         1490  +\`configure' configures sqlite 3.7.2 to adapt to many kinds of systems.
  1491   1491   
  1492   1492   Usage: $0 [OPTION]... [VAR=VALUE]...
  1493   1493   
  1494   1494   To assign environment variables (e.g., CC, CFLAGS...), specify them as
  1495   1495   VAR=VALUE.  See below for descriptions of some of the useful variables.
  1496   1496   
  1497   1497   Defaults for the options are specified in brackets.
................................................................................
  1548   1548     --build=BUILD     configure for building on BUILD [guessed]
  1549   1549     --host=HOST       cross-compile to build programs to run on HOST [BUILD]
  1550   1550   _ACEOF
  1551   1551   fi
  1552   1552   
  1553   1553   if test -n "$ac_init_help"; then
  1554   1554     case $ac_init_help in
  1555         -     short | recursive ) echo "Configuration of sqlite >>>>>>> BEGIN MERGE CONFLICT3.7.1============================3.7.0.1<<<<<<< END MERGE CONFLICT:";;
         1555  +     short | recursive ) echo "Configuration of sqlite 3.7.2:";;
  1556   1556      esac
  1557   1557     cat <<\_ACEOF
  1558   1558   
  1559   1559   Optional Features:
  1560   1560     --disable-option-checking  ignore unrecognized --enable/--with options
  1561   1561     --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  1562   1562     --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
................................................................................
  1666   1666       cd "$ac_pwd" || { ac_status=$?; break; }
  1667   1667     done
  1668   1668   fi
  1669   1669   
  1670   1670   test -n "$ac_init_help" && exit $ac_status
  1671   1671   if $ac_init_version; then
  1672   1672     cat <<\_ACEOF
  1673         -sqlite configure >>>>>>> BEGIN MERGE CONFLICT3.7.1============================3.7.0.1<<<<<<< END MERGE CONFLICT
         1673  +sqlite configure 3.7.2
  1674   1674   generated by GNU Autoconf 2.62
  1675   1675   
  1676   1676   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
  1677   1677   2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
  1678   1678   This configure script is free software; the Free Software Foundation
  1679   1679   gives unlimited permission to copy, distribute and modify it.
  1680   1680   _ACEOF
  1681   1681     exit
  1682   1682   fi
  1683   1683   cat >config.log <<_ACEOF
  1684   1684   This file contains any messages produced by compilers while
  1685   1685   running configure, to aid debugging if configure makes a mistake.
  1686   1686   
  1687         -It was created by sqlite $as_me >>>>>>> BEGIN MERGE CONFLICT3.7.1============================3.7.0.1<<<<<<< END MERGE CONFLICT, which was
         1687  +It was created by sqlite $as_me 3.7.2, which was
  1688   1688   generated by GNU Autoconf 2.62.  Invocation command line was
  1689   1689   
  1690   1690     $ $0 $@
  1691   1691   
  1692   1692   _ACEOF
  1693   1693   exec 5>>config.log
  1694   1694   {
................................................................................
 13968  13968   
 13969  13969   exec 6>&1
 13970  13970   
 13971  13971   # Save the log message, to keep $[0] and so on meaningful, and to
 13972  13972   # report actual input values of CONFIG_FILES etc. instead of their
 13973  13973   # values after options handling.
 13974  13974   ac_log="
 13975         -This file was extended by sqlite $as_me >>>>>>> BEGIN MERGE CONFLICT3.7.1============================3.7.0.1<<<<<<< END MERGE CONFLICT, which was
        13975  +This file was extended by sqlite $as_me 3.7.2, which was
 13976  13976   generated by GNU Autoconf 2.62.  Invocation command line was
 13977  13977   
 13978  13978     CONFIG_FILES    = $CONFIG_FILES
 13979  13979     CONFIG_HEADERS  = $CONFIG_HEADERS
 13980  13980     CONFIG_LINKS    = $CONFIG_LINKS
 13981  13981     CONFIG_COMMANDS = $CONFIG_COMMANDS
 13982  13982     $ $0 $@
................................................................................
 14021  14021   $config_commands
 14022  14022   
 14023  14023   Report bugs to <bug-autoconf@gnu.org>."
 14024  14024   
 14025  14025   _ACEOF
 14026  14026   cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 14027  14027   ac_cs_version="\\
 14028         -sqlite config.status >>>>>>> BEGIN MERGE CONFLICT3.7.1============================3.7.0.1<<<<<<< END MERGE CONFLICT
        14028  +sqlite config.status 3.7.2
 14029  14029   configured by $0, generated by GNU Autoconf 2.62,
 14030  14030     with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 14031  14031   
 14032  14032   Copyright (C) 2008 Free Software Foundation, Inc.
 14033  14033   This config.status script is free software; the Free Software Foundation
 14034  14034   gives unlimited permission to copy, distribute and modify it."
 14035  14035   

Changes to src/backup.c.

   216    216   
   217    217     /* Catch the case where the destination is an in-memory database and the
   218    218     ** page sizes of the source and destination differ. 
   219    219     */
   220    220     if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){
   221    221       rc = SQLITE_READONLY;
   222    222     }
          223  +
          224  +#ifdef SQLITE_HAS_CODEC
          225  +  /* Backup is not possible if the page size of the destination is changing
          226  +  ** a a codec is in use.
          227  +  */
          228  +  if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){
          229  +    rc = SQLITE_READONLY;
          230  +  }
          231  +#endif
   223    232   
   224    233     /* This loop runs once for each destination page spanned by the source 
   225    234     ** page. For each iteration, variable iOff is set to the byte offset
   226    235     ** of the destination page.
   227    236     */
   228    237     for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOff<iEnd; iOff+=nDestPgsz){
   229    238       DbPage *pDestPg = 0;

Changes to src/btree.c.

   726    726   }
   727    727   
   728    728   #ifndef SQLITE_OMIT_AUTOVACUUM
   729    729   /*
   730    730   ** Given a page number of a regular database page, return the page
   731    731   ** number for the pointer-map page that contains the entry for the
   732    732   ** input page number.
          733  +**
          734  +** Return 0 (not a valid page) for pgno==1 since there is
          735  +** no pointer map associated with page 1.  The integrity_check logic
          736  +** requires that ptrmapPageno(*,1)!=1.
   733    737   */
   734    738   static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){
   735    739     int nPagesPerMapPage;
   736    740     Pgno iPtrMap, ret;
   737    741     assert( sqlite3_mutex_held(pBt->mutex) );
          742  +  if( pgno<2 ) return 0;
   738    743     nPagesPerMapPage = (pBt->usableSize/5)+1;
   739    744     iPtrMap = (pgno-2)/nPagesPerMapPage;
   740    745     ret = (iPtrMap*nPagesPerMapPage) + 2; 
   741    746     if( ret==PENDING_BYTE_PAGE(pBt) ){
   742    747       ret++;
   743    748     }
   744    749     return ret;
................................................................................
  1378   1383   
  1379   1384     if( !pPage->isInit ){
  1380   1385       u16 pc;            /* Address of a freeblock within pPage->aData[] */
  1381   1386       u8 hdr;            /* Offset to beginning of page header */
  1382   1387       u8 *data;          /* Equal to pPage->aData */
  1383   1388       BtShared *pBt;        /* The main btree structure */
  1384   1389       int usableSize;    /* Amount of usable space on each page */
  1385         -    int cellOffset;    /* Offset from start of page to first cell pointer */
         1390  +    u16 cellOffset;    /* Offset from start of page to first cell pointer */
  1386   1391       int nFree;         /* Number of unused bytes on the page */
  1387   1392       int top;           /* First byte of the cell content area */
  1388   1393       int iCellFirst;    /* First allowable cell or freeblock offset */
  1389   1394       int iCellLast;     /* Last possible cell or freeblock offset */
  1390   1395   
  1391   1396       pBt = pPage->pBt;
  1392   1397   
................................................................................
  1493   1498       memset(&data[hdr], 0, pBt->usableSize - hdr);
  1494   1499     }
  1495   1500     data[hdr] = (char)flags;
  1496   1501     first = hdr + 8 + 4*((flags&PTF_LEAF)==0 ?1:0);
  1497   1502     memset(&data[hdr+1], 0, 4);
  1498   1503     data[hdr+7] = 0;
  1499   1504     put2byte(&data[hdr+5], pBt->usableSize);
  1500         -  pPage->nFree = pBt->usableSize - first;
         1505  +  pPage->nFree = (u16)(pBt->usableSize - first);
  1501   1506     decodeFlags(pPage, flags);
  1502   1507     pPage->hdrOffset = hdr;
  1503   1508     pPage->cellOffset = first;
  1504   1509     pPage->nOverflow = 0;
  1505   1510     assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
  1506   1511     pPage->maskPage = (u16)(pBt->pageSize - 1);
  1507   1512     pPage->nCell = 0;
................................................................................
  2322   2327        || pageSize>SQLITE_MAX_PAGE_SIZE 
  2323   2328        || pageSize<=256 
  2324   2329       ){
  2325   2330         goto page1_init_failed;
  2326   2331       }
  2327   2332       assert( (pageSize & 7)==0 );
  2328   2333       usableSize = pageSize - page1[20];
  2329         -    if( pageSize!=pBt->pageSize ){
         2334  +    if( (u32)pageSize!=pBt->pageSize ){
  2330   2335         /* After reading the first page of the database assuming a page size
  2331   2336         ** of BtShared.pageSize, we have discovered that the page-size is
  2332   2337         ** actually pageSize. Unlock the database, leave pBt->pPage1 at
  2333   2338         ** zero and return SQLITE_OK. The caller will call this function
  2334   2339         ** again with the correct page-size.
  2335   2340         */
  2336   2341         releasePage(pPage1);
................................................................................
  2361   2366     ** cells can will fit on one page.  We assume a 10-byte page header.
  2362   2367     ** Besides the payload, the cell must store:
  2363   2368     **     2-byte pointer to the cell
  2364   2369     **     4-byte child pointer
  2365   2370     **     9-byte nKey value
  2366   2371     **     4-byte nData value
  2367   2372     **     4-byte overflow page pointer
  2368         -  ** So a cell consists of a 2-byte poiner, a header which is as much as
         2373  +  ** So a cell consists of a 2-byte pointer, a header which is as much as
  2369   2374     ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow
  2370   2375     ** page pointer.
  2371   2376     */
  2372         -  pBt->maxLocal = (pBt->usableSize-12)*64/255 - 23;
  2373         -  pBt->minLocal = (pBt->usableSize-12)*32/255 - 23;
  2374         -  pBt->maxLeaf = pBt->usableSize - 35;
  2375         -  pBt->minLeaf = (pBt->usableSize-12)*32/255 - 23;
         2377  +  pBt->maxLocal = (u16)((pBt->usableSize-12)*64/255 - 23);
         2378  +  pBt->minLocal = (u16)((pBt->usableSize-12)*32/255 - 23);
         2379  +  pBt->maxLeaf = (u16)(pBt->usableSize - 35);
         2380  +  pBt->minLeaf = (u16)((pBt->usableSize-12)*32/255 - 23);
  2376   2381     assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) );
  2377   2382     pBt->pPage1 = pPage1;
  2378   2383     pBt->nPage = nPage;
  2379   2384     return SQLITE_OK;
  2380   2385   
  2381   2386   page1_init_failed:
  2382   2387     releasePage(pPage1);
................................................................................
  2421   2426     pP1 = pBt->pPage1;
  2422   2427     assert( pP1!=0 );
  2423   2428     data = pP1->aData;
  2424   2429     rc = sqlite3PagerWrite(pP1->pDbPage);
  2425   2430     if( rc ) return rc;
  2426   2431     memcpy(data, zMagicHeader, sizeof(zMagicHeader));
  2427   2432     assert( sizeof(zMagicHeader)==16 );
  2428         -  data[16] = (pBt->pageSize>>8)&0xff;
  2429         -  data[17] = (pBt->pageSize>>16)&0xff;
         2433  +  data[16] = (u8)((pBt->pageSize>>8)&0xff);
         2434  +  data[17] = (u8)((pBt->pageSize>>16)&0xff);
  2430   2435     data[18] = 1;
  2431   2436     data[19] = 1;
  2432   2437     assert( pBt->usableSize<=pBt->pageSize && pBt->usableSize+255>=pBt->pageSize);
  2433   2438     data[20] = (u8)(pBt->pageSize - pBt->usableSize);
  2434   2439     data[21] = 64;
  2435   2440     data[22] = 32;
  2436   2441     data[23] = 32;
................................................................................
  4798   4803           if( rc ){
  4799   4804             goto end_allocate_page;
  4800   4805           }
  4801   4806           if( k==0 ){
  4802   4807             if( !pPrevTrunk ){
  4803   4808               memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
  4804   4809             }else{
         4810  +            rc = sqlite3PagerWrite(pPrevTrunk->pDbPage);
         4811  +            if( rc!=SQLITE_OK ){
         4812  +              goto end_allocate_page;
         4813  +            }
  4805   4814               memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4);
  4806   4815             }
  4807   4816           }else{
  4808   4817             /* The trunk page is required by the caller but it contains 
  4809   4818             ** pointers to free-list leaves. The first leaf becomes a trunk
  4810   4819             ** page in this case.
  4811   4820             */
................................................................................
  5104   5113   */
  5105   5114   static int clearCell(MemPage *pPage, unsigned char *pCell){
  5106   5115     BtShared *pBt = pPage->pBt;
  5107   5116     CellInfo info;
  5108   5117     Pgno ovflPgno;
  5109   5118     int rc;
  5110   5119     int nOvfl;
  5111         -  u16 ovflPageSize;
         5120  +  u32 ovflPageSize;
  5112   5121   
  5113   5122     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  5114   5123     btreeParseCellPtr(pPage, pCell, &info);
  5115   5124     if( info.iOverflow==0 ){
  5116   5125       return SQLITE_OK;  /* No overflow pages. Return without doing anything */
  5117   5126     }
  5118   5127     ovflPgno = get4byte(&pCell[info.iOverflow]);
................................................................................
  5556   5565     Pgno pgnoNew;                        /* Page number of pNew */
  5557   5566   
  5558   5567     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  5559   5568     assert( sqlite3PagerIswriteable(pParent->pDbPage) );
  5560   5569     assert( pPage->nOverflow==1 );
  5561   5570   
  5562   5571     /* This error condition is now caught prior to reaching this function */
  5563         -  if( NEVER(pPage->nCell<=0) ) return SQLITE_CORRUPT_BKPT;
         5572  +  if( pPage->nCell<=0 ) return SQLITE_CORRUPT_BKPT;
  5564   5573   
  5565   5574     /* Allocate a new page. This page will become the right-sibling of 
  5566   5575     ** pPage. Make the parent page writable, so that the new divider cell
  5567   5576     ** may be inserted. If both these operations are successful, proceed.
  5568   5577     */
  5569   5578     rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
  5570   5579   
................................................................................
  5964   5973       if( i<nOld-1 && !leafData){
  5965   5974         u16 sz = (u16)szNew[i];
  5966   5975         u8 *pTemp;
  5967   5976         assert( nCell<nMaxCells );
  5968   5977         szCell[nCell] = sz;
  5969   5978         pTemp = &aSpace1[iSpace1];
  5970   5979         iSpace1 += sz;
  5971         -      assert( sz<=pBt->pageSize/4 );
         5980  +      assert( sz<=pBt->maxLocal+23 );
  5972   5981         assert( iSpace1<=pBt->pageSize );
  5973   5982         memcpy(pTemp, apDiv[i], sz);
  5974   5983         apCell[nCell] = pTemp+leafCorrection;
  5975   5984         assert( leafCorrection==0 || leafCorrection==4 );
  5976   5985         szCell[nCell] = szCell[nCell] - leafCorrection;
  5977   5986         if( !pOld->leaf ){
  5978   5987           assert( leafCorrection==0 );
................................................................................
  6210   6219           */
  6211   6220           if( szCell[j]==4 ){
  6212   6221             assert(leafCorrection==4);
  6213   6222             sz = cellSizePtr(pParent, pCell);
  6214   6223           }
  6215   6224         }
  6216   6225         iOvflSpace += sz;
  6217         -      assert( sz<=pBt->pageSize/4 );
         6226  +      assert( sz<=pBt->maxLocal+23 );
  6218   6227         assert( iOvflSpace<=pBt->pageSize );
  6219   6228         insertCell(pParent, nxDiv, pCell, sz, pTemp, pNew->pgno, &rc);
  6220   6229         if( rc!=SQLITE_OK ) goto balance_cleanup;
  6221   6230         assert( sqlite3PagerIswriteable(pParent->pDbPage) );
  6222   6231   
  6223   6232         j++;
  6224   6233         nxDiv++;

Changes to src/expr.c.

   562    562       testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
   563    563       testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
   564    564       if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
   565    565         sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
   566    566             db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
   567    567       }
   568    568       if( i>pParse->nVar ){
   569         -      pParse->nVar = i;
          569  +      pParse->nVar = (int)i;
   570    570       }
   571    571     }else{
   572    572       /* Wildcards like ":aaa", "$aaa" or "@aaa".  Reuse the same variable
   573    573       ** number as the prior appearance of the same name, or if the name
   574    574       ** has never appeared before, reuse the same variable number
   575    575       */
   576    576       int i;

Changes to src/mem2.c.

   374    374     sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
   375    375   }
   376    376   
   377    377   /*
   378    378   ** Set the "type" of an allocation.
   379    379   */
   380    380   void sqlite3MemdebugSetType(void *p, u8 eType){
   381         -  if( p ){
          381  +  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
   382    382       struct MemBlockHdr *pHdr;
   383    383       pHdr = sqlite3MemsysGetHeader(p);
   384    384       assert( pHdr->iForeGuard==FOREGUARD );
   385    385       pHdr->eType = eType;
   386    386     }
   387    387   }
   388    388   
................................................................................
   393    393   ** This routine is designed for use within an assert() statement, to
   394    394   ** verify the type of an allocation.  For example:
   395    395   **
   396    396   **     assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
   397    397   */
   398    398   int sqlite3MemdebugHasType(void *p, u8 eType){
   399    399     int rc = 1;
   400         -  if( p ){
          400  +  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
   401    401       struct MemBlockHdr *pHdr;
   402    402       pHdr = sqlite3MemsysGetHeader(p);
   403    403       assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
   404    404       if( (pHdr->eType&eType)==0 ){
   405    405         rc = 0;
   406    406       }
   407    407     }
................................................................................
   415    415   ** This routine is designed for use within an assert() statement, to
   416    416   ** verify the type of an allocation.  For example:
   417    417   **
   418    418   **     assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
   419    419   */
   420    420   int sqlite3MemdebugNoType(void *p, u8 eType){
   421    421     int rc = 1;
   422         -  if( p ){
          422  +  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
   423    423       struct MemBlockHdr *pHdr;
   424    424       pHdr = sqlite3MemsysGetHeader(p);
   425    425       assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
   426    426       if( (pHdr->eType&eType)!=0 ){
   427    427         rc = 0;
   428    428       }
   429    429     }

Changes to src/pager.c.

  1053   1053     assert( !pPager->exclusiveMode );
  1054   1054     assert( eLock==NO_LOCK || eLock==SHARED_LOCK );
  1055   1055     assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 );
  1056   1056     if( isOpen(pPager->fd) ){
  1057   1057       assert( pPager->eLock>=eLock );
  1058   1058       rc = sqlite3OsUnlock(pPager->fd, eLock);
  1059   1059       if( pPager->eLock!=UNKNOWN_LOCK ){
  1060         -      pPager->eLock = eLock;
         1060  +      pPager->eLock = (u8)eLock;
  1061   1061       }
  1062   1062       IOTRACE(("UNLOCK %p %d\n", pPager, eLock))
  1063   1063     }
  1064   1064     return rc;
  1065   1065   }
  1066   1066   
  1067   1067   /*
................................................................................
  1077   1077   static int pagerLockDb(Pager *pPager, int eLock){
  1078   1078     int rc = SQLITE_OK;
  1079   1079   
  1080   1080     assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK );
  1081   1081     if( pPager->eLock<eLock || pPager->eLock==UNKNOWN_LOCK ){
  1082   1082       rc = sqlite3OsLock(pPager->fd, eLock);
  1083   1083       if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){
  1084         -      pPager->eLock = eLock;
         1084  +      pPager->eLock = (u8)eLock;
  1085   1085         IOTRACE(("LOCK %p %d\n", pPager, eLock))
  1086   1086       }
  1087   1087     }
  1088   1088     return rc;
  1089   1089   }
  1090   1090   
  1091   1091   /*
................................................................................
  1157   1157   ** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES
  1158   1158   ** is defined, and NDEBUG is not defined, an assert() statement checks
  1159   1159   ** that the page is either dirty or still matches the calculated page-hash.
  1160   1160   */
  1161   1161   #define CHECK_PAGE(x) checkPage(x)
  1162   1162   static void checkPage(PgHdr *pPg){
  1163   1163     Pager *pPager = pPg->pPager;
  1164         -  assert( !pPg->pageHash || pPager->errCode
  1165         -      || (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) );
         1164  +  assert( pPager->eState!=PAGER_ERROR );
         1165  +  assert( (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) );
  1166   1166   }
  1167   1167   
  1168   1168   #else
  1169   1169   #define pager_datahash(X,Y)  0
  1170   1170   #define pager_pagehash(X)  0
         1171  +#define pager_set_pagehash(X)
  1171   1172   #define CHECK_PAGE(x)
  1172   1173   #endif  /* SQLITE_CHECK_PAGES */
  1173   1174   
  1174   1175   /*
  1175   1176   ** When this is called the journal file for pager pPager must be open.
  1176   1177   ** This function attempts to read a master journal file name from the 
  1177   1178   ** end of the file and, if successful, copies it into memory supplied 
................................................................................
  1504   1505   
  1505   1506       /* Read the page-size and sector-size journal header fields. */
  1506   1507       if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize))
  1507   1508        || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+24, &iPageSize))
  1508   1509       ){
  1509   1510         return rc;
  1510   1511       }
         1512  +
         1513  +    /* Versions of SQLite prior to 3.5.8 set the page-size field of the
         1514  +    ** journal header to zero. In this case, assume that the Pager.pageSize
         1515  +    ** variable is already set to the correct page size.
         1516  +    */
         1517  +    if( iPageSize==0 ){
         1518  +      iPageSize = pPager->pageSize;
         1519  +    }
  1511   1520   
  1512   1521       /* Check that the values read from the page-size and sector-size fields
  1513   1522       ** are within range. To be 'in range', both values need to be a power
  1514   1523       ** of two greater than or equal to 512 or 32, and not greater than their 
  1515   1524       ** respective compile time maximum limits.
  1516   1525       */
  1517   1526       if( iPageSize<512                  || iSectorSize<32
................................................................................
  1925   1934              || pPager->journalMode==PAGER_JOURNALMODE_WAL 
  1926   1935         );
  1927   1936         sqlite3OsClose(pPager->jfd);
  1928   1937         if( !pPager->tempFile ){
  1929   1938           rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
  1930   1939         }
  1931   1940       }
         1941  +  }
  1932   1942   
  1933   1943   #ifdef SQLITE_CHECK_PAGES
  1934         -    sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
         1944  +  sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
         1945  +  if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){
         1946  +    PgHdr *p = pager_lookup(pPager, 1);
         1947  +    if( p ){
         1948  +      p->pageHash = 0;
         1949  +      sqlite3PagerUnref(p);
         1950  +    }
         1951  +  }
  1935   1952   #endif
  1936         -  }
         1953  +
  1937   1954     sqlite3BitvecDestroy(pPager->pInJournal);
  1938   1955     pPager->pInJournal = 0;
  1939   1956     pPager->nRec = 0;
  1940   1957     sqlite3PcacheCleanAll(pPager->pPCache);
  1941   1958     sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
  1942   1959   
  1943   1960     if( pagerUseWal(pPager) ){
................................................................................
  2276   2293         ** be written out into the database file before its journal file
  2277   2294         ** segment is synced. If a crash occurs during or following this,
  2278   2295         ** database corruption may ensue.
  2279   2296         */
  2280   2297         assert( !pagerUseWal(pPager) );
  2281   2298         sqlite3PcacheMakeClean(pPg);
  2282   2299       }
  2283         -#ifdef SQLITE_CHECK_PAGES
  2284         -    pPg->pageHash = pager_pagehash(pPg);
  2285         -#endif
         2300  +    pager_set_pagehash(pPg);
         2301  +
  2286   2302       /* If this was page 1, then restore the value of Pager.dbFileVers.
  2287   2303       ** Do this before any decoding. */
  2288   2304       if( pgno==1 ){
  2289   2305         memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers));
  2290   2306       }
  2291   2307   
  2292   2308       /* Decode the page just read from disk */
................................................................................
  2917   2933     );
  2918   2934     if( rc==SQLITE_OK && pPager->pBackup ){
  2919   2935       PgHdr *p;
  2920   2936       for(p=pList; p; p=p->pDirty){
  2921   2937         sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
  2922   2938       }
  2923   2939     }
         2940  +
         2941  +#ifdef SQLITE_CHECK_PAGES
         2942  +  {
         2943  +    PgHdr *p;
         2944  +    for(p=pList; p; p=p->pDirty) pager_set_pagehash(p);
         2945  +  }
         2946  +#endif
         2947  +
  2924   2948     return rc;
  2925   2949   }
  2926   2950   
  2927   2951   /*
  2928   2952   ** Begin a read transaction on the WAL.
  2929   2953   **
  2930   2954   ** This routine used to be called "pagerOpenSnapshot()" because it essentially
................................................................................
  3362   3386   
  3363   3387     u32 pageSize = *pPageSize;
  3364   3388     assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) );
  3365   3389     if( (pPager->memDb==0 || pPager->dbSize==0)
  3366   3390      && sqlite3PcacheRefCount(pPager->pPCache)==0 
  3367   3391      && pageSize && pageSize!=(u32)pPager->pageSize 
  3368   3392     ){
  3369         -    char *pNew;                 /* New temp space */
         3393  +    char *pNew = NULL;             /* New temp space */
  3370   3394       i64 nByte = 0;
  3371   3395   
  3372   3396       if( pPager->eState>PAGER_OPEN && isOpen(pPager->fd) ){
  3373   3397         rc = sqlite3OsFileSize(pPager->fd, &nByte);
  3374   3398       }
  3375   3399       if( rc==SQLITE_OK ){
  3376   3400         pNew = (char *)sqlite3PageMalloc(pageSize);
  3377   3401         if( !pNew ) rc = SQLITE_NOMEM;
  3378   3402       }
  3379   3403   
  3380   3404       if( rc==SQLITE_OK ){
  3381   3405         pager_reset(pPager);
  3382         -      pPager->dbSize = nByte/pageSize;
         3406  +      pPager->dbSize = (Pgno)(nByte/pageSize);
  3383   3407         pPager->pageSize = pageSize;
  3384   3408         sqlite3PageFree(pPager->pTmpSpace);
  3385   3409         pPager->pTmpSpace = pNew;
  3386   3410         sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
  3387   3411       }
  3388   3412     }
  3389   3413   
................................................................................
  3948   3972                      PAGERID(pPager), pgno, pager_pagehash(pList)));
  3949   3973         IOTRACE(("PGOUT %p %d\n", pPager, pgno));
  3950   3974         PAGER_INCR(sqlite3_pager_writedb_count);
  3951   3975         PAGER_INCR(pPager->nWrite);
  3952   3976       }else{
  3953   3977         PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno));
  3954   3978       }
  3955         -#ifdef SQLITE_CHECK_PAGES
  3956         -    pList->pageHash = pager_pagehash(pList);
  3957         -#endif
         3979  +    pager_set_pagehash(pList);
  3958   3980       pList = pList->pDirty;
  3959   3981     }
  3960   3982   
  3961   3983     return rc;
  3962   3984   }
  3963   3985   
  3964   3986   /*
................................................................................
  4139   4161   
  4140   4162     /* Mark the page as clean. */
  4141   4163     if( rc==SQLITE_OK ){
  4142   4164       PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno));
  4143   4165       sqlite3PcacheMakeClean(pPg);
  4144   4166     }
  4145   4167   
  4146         -  return pager_error(pPager, rc);
         4168  +  return pager_error(pPager, rc); 
  4147   4169   }
  4148   4170   
  4149   4171   
  4150   4172   /*
  4151   4173   ** Allocate and initialize a new Pager object and put a pointer to it
  4152   4174   ** in *ppPager. The pager should eventually be freed by passing it
  4153   4175   ** to sqlite3PagerClose().
................................................................................
  4938   4960       }else{
  4939   4961         assert( pPg->pPager==pPager );
  4940   4962         rc = readDbPage(pPg);
  4941   4963         if( rc!=SQLITE_OK ){
  4942   4964           goto pager_acquire_err;
  4943   4965         }
  4944   4966       }
  4945         -#ifdef SQLITE_CHECK_PAGES
  4946         -    pPg->pageHash = pager_pagehash(pPg);
  4947         -#endif
         4967  +    pager_set_pagehash(pPg);
  4948   4968     }
  4949   4969   
  4950   4970     return SQLITE_OK;
  4951   4971   
  4952   4972   pager_acquire_err:
  4953   4973     assert( rc!=SQLITE_OK );
  4954   4974     if( pPg ){
................................................................................
  5438   5458   */
  5439   5459   void sqlite3PagerDontWrite(PgHdr *pPg){
  5440   5460     Pager *pPager = pPg->pPager;
  5441   5461     if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
  5442   5462       PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager)));
  5443   5463       IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
  5444   5464       pPg->flags |= PGHDR_DONT_WRITE;
  5445         -#ifdef SQLITE_CHECK_PAGES
  5446         -    pPg->pageHash = pager_pagehash(pPg);
  5447         -#endif
         5465  +    pager_set_pagehash(pPg);
  5448   5466     }
  5449   5467   }
  5450   5468   
  5451   5469   /*
  5452   5470   ** This routine is called to increment the value of the database file 
  5453   5471   ** change-counter, stored as a 4-byte big-endian integer starting at 
  5454   5472   ** byte offset 24 of the pager file.

Changes to src/pcache1.c.

   196    196       sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
   197    197       iSize = sqlite3MallocSize(p);
   198    198       sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -iSize);
   199    199       sqlite3_free(p);
   200    200     }
   201    201   }
   202    202   
          203  +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
          204  +/*
          205  +** Return the size of a pache allocation
          206  +*/
          207  +static int pcache1MemSize(void *p){
          208  +  assert( sqlite3_mutex_held(pcache1.mutex) );
          209  +  if( p>=pcache1.pStart && p<pcache1.pEnd ){
          210  +    return pcache1.szSlot;
          211  +  }else{
          212  +    int iSize;
          213  +    assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
          214  +    sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
          215  +    iSize = sqlite3MallocSize(p);
          216  +    sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
          217  +    return iSize;
          218  +  }
          219  +}
          220  +#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
          221  +
   203    222   /*
   204    223   ** Allocate a new page object initially associated with cache pCache.
   205    224   */
   206    225   static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
   207    226     int nByte = sizeof(PgHdr1) + pCache->szPage;
   208    227     void *pPg = pcache1Alloc(nByte);
   209    228     PgHdr1 *p;
................................................................................
   744    763   */
   745    764   int sqlite3PcacheReleaseMemory(int nReq){
   746    765     int nFree = 0;
   747    766     if( pcache1.pStart==0 ){
   748    767       PgHdr1 *p;
   749    768       pcache1EnterMutex();
   750    769       while( (nReq<0 || nFree<nReq) && (p=pcache1.pLruTail) ){
   751         -      nFree += sqlite3MallocSize(PGHDR1_TO_PAGE(p));
          770  +      nFree += pcache1MemSize(PGHDR1_TO_PAGE(p));
   752    771         pcache1PinPage(p);
   753    772         pcache1RemoveFromHash(p);
   754    773         pcache1FreePage(p);
   755    774       }
   756    775       pcache1LeaveMutex();
   757    776     }
   758    777     return nFree;

Changes to src/sqliteLimit.h.

   132    132   #ifndef SQLITE_MAX_VARIABLE_NUMBER
   133    133   # define SQLITE_MAX_VARIABLE_NUMBER 999
   134    134   #endif
   135    135   
   136    136   /* Maximum page size.  The upper bound on this value is 65536.  This a limit
   137    137   ** imposed by the use of 16-bit offsets within each page.
   138    138   **
   139         -** If this limit is changed, then the compiled library is technically
   140         -** incompatible with an SQLite library compiled with a different limit. If
   141         -** a process operating on a database with a page-size of 65536 bytes 
   142         -** crashes, then an instance of SQLite compiled with the default page-size 
   143         -** limit will not be able to rollback the aborted transaction. This could
   144         -** lead to database corruption.
          139  +** Earlier versions of SQLite allowed the user to change this value at
          140  +** compile time. This is no longer permitted, on the grounds that it creates
          141  +** a library that is technically incompatible with an SQLite library 
          142  +** compiled with a different limit. If a process operating on a database 
          143  +** with a page-size of 65536 bytes crashes, then an instance of SQLite 
          144  +** compiled with the default page-size limit will not be able to rollback 
          145  +** the aborted transaction. This could lead to database corruption.
   145    146   */
   146         -#ifndef SQLITE_MAX_PAGE_SIZE
   147         -# define SQLITE_MAX_PAGE_SIZE 65536
          147  +#ifdef SQLITE_MAX_PAGE_SIZE
          148  +# undef SQLITE_MAX_PAGE_SIZE
   148    149   #endif
          150  +#define SQLITE_MAX_PAGE_SIZE 65536
   149    151   
   150    152   
   151    153   /*
   152    154   ** The default size of a database page.
   153    155   */
   154    156   #ifndef SQLITE_DEFAULT_PAGE_SIZE
   155    157   # define SQLITE_DEFAULT_PAGE_SIZE 1024

Changes to src/tclsqlite.c.

  3011   3011   **
  3012   3012   ** This Tcl module contains only a single new Tcl command named "sqlite".
  3013   3013   ** (Hence there is no namespace.  There is no point in using a namespace
  3014   3014   ** if the extension only supplies one new name!)  The "sqlite" command is
  3015   3015   ** used to open a new SQLite database.  See the DbMain() routine above
  3016   3016   ** for additional information.
  3017   3017   */
  3018         -EXTERN int Sqlite3_Init(Tcl_Interp *interp){
         3018  +int Sqlite3_Init(Tcl_Interp *interp){
  3019   3019     Tcl_InitStubs(interp, "8.4", 0);
  3020   3020     Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
  3021   3021     Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION);
  3022   3022     Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
  3023   3023     Tcl_PkgProvide(interp, "sqlite", PACKAGE_VERSION);
  3024   3024     return TCL_OK;
  3025   3025   }
  3026         -EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
  3027         -EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
  3028         -EXTERN int Tclsqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
  3029         -EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
  3030         -EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
  3031         -EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; }
  3032         -EXTERN int Tclsqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;}
         3026  +int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
         3027  +int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
         3028  +int Tclsqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
         3029  +int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
         3030  +int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
         3031  +int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; }
         3032  +int Tclsqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;}
  3033   3033   
  3034   3034   
  3035   3035   #ifndef SQLITE_3_SUFFIX_ONLY
  3036         -EXTERN int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
  3037         -EXTERN int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
  3038         -EXTERN int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
  3039         -EXTERN int Tclsqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
  3040         -EXTERN int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
  3041         -EXTERN int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
  3042         -EXTERN int Sqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; }
  3043         -EXTERN int Tclsqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;}
         3036  +int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
         3037  +int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
         3038  +int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
         3039  +int Tclsqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
         3040  +int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
         3041  +int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
         3042  +int Sqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; }
         3043  +int Tclsqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;}
  3044   3044   #endif
  3045   3045   
  3046   3046   #ifdef TCLSH
  3047   3047   /*****************************************************************************
  3048   3048   ** All of the code that follows is used to build standalone TCL interpreters
  3049   3049   ** that are statically linked with SQLite.  Enable these by compiling
  3050   3050   ** with -DTCLSH=n where n can be 1 or 2.  An n of 1 generates a standard

Changes to src/wal.c.

  1131   1131         rc = walIndexAppend(pWal, ++iFrame, pgno);
  1132   1132         if( rc!=SQLITE_OK ) break;
  1133   1133   
  1134   1134         /* If nTruncate is non-zero, this is a commit record. */
  1135   1135         if( nTruncate ){
  1136   1136           pWal->hdr.mxFrame = iFrame;
  1137   1137           pWal->hdr.nPage = nTruncate;
  1138         -        pWal->hdr.szPage = (szPage&0xff00) | (szPage>>16);
         1138  +        pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
  1139   1139           testcase( szPage<=32768 );
  1140   1140           testcase( szPage>=65536 );
  1141   1141           aFrameCksum[0] = pWal->hdr.aFrameCksum[0];
  1142   1142           aFrameCksum[1] = pWal->hdr.aFrameCksum[1];
  1143   1143         }
  1144   1144       }
  1145   1145   
................................................................................
  2558   2558       iFrame++;
  2559   2559       nLast--;
  2560   2560       rc = walIndexAppend(pWal, iFrame, pLast->pgno);
  2561   2561     }
  2562   2562   
  2563   2563     if( rc==SQLITE_OK ){
  2564   2564       /* Update the private copy of the header. */
  2565         -    pWal->hdr.szPage = (szPage&0xff00) | (szPage>>16);
         2565  +    pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
  2566   2566       testcase( szPage<=32768 );
  2567   2567       testcase( szPage>=65536 );
  2568   2568       pWal->hdr.mxFrame = iFrame;
  2569   2569       if( isCommit ){
  2570   2570         pWal->hdr.iChange++;
  2571   2571         pWal->hdr.nPage = nTruncate;
  2572   2572       }

Added test/backcompat.test.

            1  +# 2010 August 19
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library.  The
           12  +# focus of this file is testing that the current version of SQLite
           13  +# is capable of reading and writing databases created by previous
           14  +# versions, and vice-versa.
           15  +#
           16  +# To use this test, old versions of the testfixture process should be
           17  +# copied into the working directory alongside the new version. The old
           18  +# versions should be named "testfixtureXXX" (or testfixtureXXX.exe on
           19  +# windows), where XXX can be any string.
           20  +#
           21  +# This test file uses the tcl code for controlling a second testfixture
           22  +# process located in lock_common.tcl. See the commments in lock_common.tcl 
           23  +# for documentation of the available commands.
           24  +#
           25  +
           26  +set testdir [file dirname $argv0]
           27  +source $testdir/tester.tcl
           28  +source $testdir/lock_common.tcl
           29  +source $testdir/malloc_common.tcl
           30  +db close
           31  +
           32  +# Search for binaries to test against. Any executable files that match
           33  +# our naming convention are assumed to be testfixture binaries to test
           34  +# against.
           35  +#
           36  +set binaries [list]
           37  +set pattern "[file tail [info nameofexec]]?*"
           38  +if {$tcl_platform(platform)=="windows"} {
           39  +  set pattern [string map {\.exe {}} $pattern]
           40  +}
           41  +foreach file [glob -nocomplain $pattern] {
           42  +  if {[file executable $file]} {lappend binaries $file}
           43  +}
           44  +if {[llength $binaries]==0} {
           45  +  puts "WARNING: No historical binaries to test against."
           46  +  puts "WARNING: No backwards-compatibility tests have been run."
           47  +  finish_test
           48  +  return
           49  +}
           50  +proc get_version {binary} {
           51  +  set chan [launch_testfixture $binary]
           52  +  set v [testfixture $chan { sqlite3 -version }]
           53  +  close $chan
           54  +  set v
           55  +}
           56  +foreach bin $binaries {
           57  +  puts -nonewline "Testing against $bin - "
           58  +  flush stdout
           59  +  puts "version [get_version $bin]"
           60  +}
           61  +
           62  +proc do_backcompat_test {rv bin1 bin2 script} {
           63  +
           64  +  file delete -force test.db
           65  +
           66  +  if {$bin1 != ""} { set ::bc_chan1 [launch_testfixture $bin1] }
           67  +  set ::bc_chan2 [launch_testfixture $bin2]
           68  +
           69  +  if { $rv } {
           70  +    proc code2 {tcl} { uplevel #0 $tcl }
           71  +    if {$bin1 != ""} { proc code2 {tcl} { testfixture $::bc_chan1 $tcl } }
           72  +    proc code1 {tcl} { testfixture $::bc_chan2 $tcl }
           73  +  } else {
           74  +    proc code1 {tcl} { uplevel #0 $tcl }
           75  +    if {$bin1 != ""} { proc code1 {tcl} { testfixture $::bc_chan1 $tcl } }
           76  +    proc code2 {tcl} { testfixture $::bc_chan2 $tcl }
           77  +  }
           78  +
           79  +  proc sql1 sql { code1 [list db eval $sql] }
           80  +  proc sql2 sql { code2 [list db eval $sql] }
           81  +
           82  +  code1 { sqlite3 db test.db }
           83  +  code2 { sqlite3 db test.db }
           84  +
           85  +  uplevel $script
           86  +
           87  +  catch { code1 { db close } }
           88  +  catch { code2 { db close } }
           89  +  catch { close $::bc_chan2 }
           90  +  catch { close $::bc_chan1 }
           91  +}
           92  +
           93  +array set ::incompatible [list]
           94  +proc do_allbackcompat_test {script} {
           95  +
           96  +  foreach bin $::binaries {
           97  +    set nErr [set_test_counter errors]
           98  +    foreach dir {0 1} {
           99  +
          100  +      set bintag [string map {testfixture {}} $bin]
          101  +      set bintag [string map {\.exe {}} $bintag]
          102  +      if {$bintag == ""} {set bintag self}
          103  +      set ::bcname ".$bintag.$dir."
          104  +
          105  +      rename do_test _do_test
          106  +      proc do_test {nm sql res} {
          107  +        set nm [regsub {\.} $nm $::bcname]
          108  +        uplevel [list _do_test $nm $sql $res]
          109  +      }
          110  +
          111  +      do_backcompat_test $dir {} $bin $script
          112  +
          113  +      rename do_test {}
          114  +      rename _do_test do_test
          115  +    }
          116  +    if { $nErr < [set_test_counter errors] } {
          117  +      set ::incompatible([get_version $bin]) 1
          118  +    }
          119  +  }
          120  +}
          121  +
          122  +proc read_file {zFile} {
          123  +  set zData {}
          124  +  if {[file exists $zFile]} {
          125  +    set fd [open $zFile]
          126  +    fconfigure $fd -translation binary -encoding binary
          127  +
          128  +    if {[file size $zFile]<=$::sqlite_pending_byte || $zFile != "test.db"} {
          129  +      set zData [read $fd]
          130  +    } else {
          131  +      set zData [read $fd $::sqlite_pending_byte]
          132  +      append zData [string repeat x 512]
          133  +      seek $fd [expr $::sqlite_pending_byte+512] start
          134  +      append zData [read $fd]
          135  +    }
          136  +
          137  +    close $fd
          138  +  }
          139  +  return $zData
          140  +}
          141  +proc write_file {zFile zData} {
          142  +  set fd [open $zFile w]
          143  +  fconfigure $fd -translation binary -encoding binary
          144  +  puts -nonewline $fd $zData
          145  +  close $fd
          146  +}
          147  +proc read_file_system {} {
          148  +  set ret [list]
          149  +  foreach f {test.db test.db-journal test.db-wal} { lappend ret [read_file $f] }
          150  +  set ret
          151  +}
          152  +proc write_file_system {data} {
          153  +  foreach f {test.db test.db-journal test.db-wal} d $data { 
          154  +    if {[string length $d] == 0} {
          155  +      file delete -force $f
          156  +    } else {
          157  +      write_file $f $d
          158  +    }
          159  +  }
          160  +}
          161  +
          162  +#-------------------------------------------------------------------------
          163  +# Actual tests begin here.
          164  +#
          165  +# This first block of tests checks to see that the same database and 
          166  +# journal files can be used by old and new versions. WAL and wal-index
          167  +# files are tested separately below.
          168  +#
          169  +do_allbackcompat_test {
          170  +
          171  +  # Test that database files are backwards compatible.
          172  +  #
          173  +  do_test backcompat-1.1.1 { sql1 { 
          174  +    CREATE TABLE t1(a PRIMARY KEY, b UNIQUE);
          175  +    INSERT INTO t1 VALUES('abc', 'def');
          176  +  } } {}
          177  +  do_test backcompat-1.1.2 { sql2 { SELECT * FROM t1; } } {abc def}
          178  +  do_test backcompat-1.1.3 { sql2 { INSERT INTO t1 VALUES('ghi', 'jkl'); } } {}
          179  +  do_test backcompat-1.1.4 { sql1 { SELECT * FROM t1; } } {abc def ghi jkl}
          180  +  do_test backcompat-1.1.5 { sql1 { PRAGMA integrity_check } } {ok}
          181  +  do_test backcompat-1.1.6 { sql2 { PRAGMA integrity_check } } {ok}
          182  +
          183  +  # Test that one version can roll back a hot-journal file left in the
          184  +  # file-system by the other version.
          185  +  #
          186  +  # Each test case is named "backcompat-1.X...", where X is either 0 or
          187  +  # 1. If it is 0, then the current version creates a journal file that
          188  +  # the old versions try to read. Otherwise, if X is 1, then the old version
          189  +  # creates the journal file and we try to read it with the current version.
          190  +  #
          191  +  do_test backcompat-1.2.1 { sql1 {
          192  +    PRAGMA cache_size = 10;
          193  +    BEGIN;
          194  +      INSERT INTO t1 VALUES(randomblob(400), randomblob(400));
          195  +      INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM t1;
          196  +      INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM t1;
          197  +      INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM t1;
          198  +      INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM t1;
          199  +    COMMIT;
          200  +  } } {}
          201  +  set cksum1 [sql1 {SELECT md5sum(a), md5sum(b) FROM t1}]
          202  +  set cksum2 [sql2 {SELECT md5sum(a), md5sum(b) FROM t1}]
          203  +  do_test backcompat-1.2.2 [list string compare $cksum1 $cksum2] 0
          204  +
          205  +  do_test backcompat-1.2.3 { sql1 {
          206  +    BEGIN;
          207  +      UPDATE t1 SET a = randomblob(500);
          208  +  } } {}
          209  +  set data [read_file_system]
          210  +
          211  +  do_test backcompat-1.2.4 { sql1 { COMMIT } } {}
          212  +
          213  +  set same [expr {[sql2 {SELECT md5sum(a), md5sum(b) FROM t1}] == $cksum2}]
          214  +  do_test backcompat-1.2.5 [list set {} $same] 0
          215  +
          216  +  code1 { db close }
          217  +  code2 { db close }
          218  +  write_file_system $data
          219  +  code1 { sqlite3 db test.db }
          220  +  code2 { sqlite3 db test.db }
          221  +
          222  +  set same [expr {[sql2 {SELECT md5sum(a), md5sum(b) FROM t1}] == $cksum2}]
          223  +  do_test backcompat-1.2.6 [list set {} $same] 1
          224  +
          225  +  do_test backcompat-1.2.7 { sql1 { PRAGMA integrity_check } } {ok}
          226  +  do_test backcompat-1.2.8 { sql2 { PRAGMA integrity_check } } {ok}
          227  +}
          228  +foreach k [lsort [array names ::incompatible]] {
          229  +  puts "ERROR: Detected journal incompatibility with version $k"
          230  +}
          231  +unset ::incompatible
          232  +
          233  +
          234  +#-------------------------------------------------------------------------
          235  +# Test that WAL and wal-index files may be shared between different 
          236  +# SQLite versions.
          237  +#
          238  +do_allbackcompat_test {
          239  +  if {[code1 {sqlite3 -version}] >= "3.7.0"
          240  +   && [code2 {sqlite3 -version}] >= "3.7.0"
          241  +  } {
          242  +
          243  +    do_test backcompat-2.1.1 { sql1 {
          244  +      PRAGMA journal_mode = WAL;
          245  +      CREATE TABLE t1(a PRIMARY KEY, b UNIQUE);
          246  +      INSERT INTO t1 VALUES('I', 1);
          247  +      INSERT INTO t1 VALUES('II', 2);
          248  +      INSERT INTO t1 VALUES('III', 3);
          249  +      SELECT * FROM t1;
          250  +    } } {wal I 1 II 2 III 3}
          251  +    do_test backcompat-2.1.2 { sql2 {
          252  +      SELECT * FROM t1;
          253  +    } } {I 1 II 2 III 3}
          254  +
          255  +    set data [read_file_system]
          256  +    code1 {db close}
          257  +    code2 {db close}
          258  +    write_file_system $data
          259  +    code1 {sqlite3 db test.db}
          260  +    code2 {sqlite3 db test.db}
          261  +
          262  +    # The WAL file now in the file-system was created by the [code1]
          263  +    # process. Check that the [code2] process can recover the log.
          264  +    #
          265  +    do_test backcompat-2.1.3 { sql2 {
          266  +      SELECT * FROM t1;
          267  +    } } {I 1 II 2 III 3}
          268  +    do_test backcompat-2.1.4 { sql1 {
          269  +      SELECT * FROM t1;
          270  +    } } {I 1 II 2 III 3}
          271  +  }
          272  +}
          273  +
          274  +finish_test

Changes to test/e_expr.test.

   858    858   do_execsql_test e_expr-13.2.7  { SELECT  5 BETWEEN 0 AND 0  != 1 }   1
   859    859   do_execsql_test e_expr-13.2.8  { SELECT (5 BETWEEN 0 AND 0) != 1 }   1
   860    860   do_execsql_test e_expr-13.2.9  { SELECT  5 BETWEEN 0 AND (0 != 1) }  0
   861    861   do_execsql_test e_expr-13.2.10 { SELECT  1 != 0  BETWEEN 0 AND 2  }  1
   862    862   do_execsql_test e_expr-13.2.11 { SELECT (1 != 0) BETWEEN 0 AND 2  }  1
   863    863   do_execsql_test e_expr-13.2.12 { SELECT  1 != (0 BETWEEN 0 AND 2) }  0
   864    864   
   865         -do_execsql_test e_expr-13.2.13  { SELECT 1 LIKE 10 BETWEEN 0 AND 2   }  1
   866         -do_execsql_test e_expr-13.2.14  { SELECT (1 LIKE 10) BETWEEN 0 AND 2 }  1
   867         -do_execsql_test e_expr-13.2.15  { SELECT 1 LIKE (10 BETWEEN 0 AND 2) }  0
   868         -do_execsql_test e_expr-13.2.16  { SELECT  6 BETWEEN 4 AND 8 LIKE 1   }  1
   869         -do_execsql_test e_expr-13.2.17  { SELECT (6 BETWEEN 4 AND 8) LIKE 1  }  1
   870         -do_execsql_test e_expr-13.2.18  { SELECT  6 BETWEEN 4 AND (8 LIKE 1) }  0
          865  +do_execsql_test e_expr-13.2.13 { SELECT 1 LIKE 10 BETWEEN 0 AND 2   }  1
          866  +do_execsql_test e_expr-13.2.14 { SELECT (1 LIKE 10) BETWEEN 0 AND 2 }  1
          867  +do_execsql_test e_expr-13.2.15 { SELECT 1 LIKE (10 BETWEEN 0 AND 2) }  0
          868  +do_execsql_test e_expr-13.2.16 { SELECT  6 BETWEEN 4 AND 8 LIKE 1   }  1
          869  +do_execsql_test e_expr-13.2.17 { SELECT (6 BETWEEN 4 AND 8) LIKE 1  }  1
          870  +do_execsql_test e_expr-13.2.18 { SELECT  6 BETWEEN 4 AND (8 LIKE 1) }  0
          871  +
          872  +do_execsql_test e_expr-13.2.19 { SELECT 0 AND 0 BETWEEN 0 AND 1   } 0
          873  +do_execsql_test e_expr-13.2.20 { SELECT 0 AND (0 BETWEEN 0 AND 1) } 0
          874  +do_execsql_test e_expr-13.2.21 { SELECT (0 AND 0) BETWEEN 0 AND 1 } 1
          875  +do_execsql_test e_expr-13.2.22 { SELECT 0 BETWEEN -1 AND 1 AND 0   } 0
          876  +do_execsql_test e_expr-13.2.23 { SELECT (0 BETWEEN -1 AND 1) AND 0 } 0
          877  +do_execsql_test e_expr-13.2.24 { SELECT 0 BETWEEN -1 AND (1 AND 0) } 1
          878  +
          879  +do_execsql_test e_expr-13.2.25 { SELECT 2 < 3 BETWEEN 0 AND 1   } 1
          880  +do_execsql_test e_expr-13.2.26 { SELECT (2 < 3) BETWEEN 0 AND 1 } 1
          881  +do_execsql_test e_expr-13.2.27 { SELECT 2 < (3 BETWEEN 0 AND 1) } 0
          882  +do_execsql_test e_expr-13.2.28 { SELECT 2 BETWEEN 1 AND 2 < 3    } 0
          883  +do_execsql_test e_expr-13.2.29 { SELECT 2 BETWEEN 1 AND (2 < 3)  } 0
          884  +do_execsql_test e_expr-13.2.30 { SELECT (2 BETWEEN 1 AND 2) < 3  } 1
          885  +
          886  +#-------------------------------------------------------------------------
          887  +# Test the statements related to the LIKE and GLOB operators.
          888  +#
          889  +# EVIDENCE-OF: R-16584-60189 The LIKE operator does a pattern matching
          890  +# comparison.
          891  +#
          892  +# EVIDENCE-OF: R-11295-04657 The operand to the right of the LIKE
          893  +# operator contains the pattern and the left hand operand contains the
          894  +# string to match against the pattern.
          895  +#
          896  +do_execsql_test e_expr-14.1.1 { SELECT 'abc%' LIKE 'abcde' } 0
          897  +do_execsql_test e_expr-14.1.2 { SELECT 'abcde' LIKE 'abc%' } 1
          898  +
          899  +# EVIDENCE-OF: R-55406-38524 A percent symbol ("%") in the LIKE pattern
          900  +# matches any sequence of zero or more characters in the string.
          901  +#
          902  +do_execsql_test e_expr-14.2.1 { SELECT 'abde'    LIKE 'ab%de' } 1
          903  +do_execsql_test e_expr-14.2.2 { SELECT 'abXde'   LIKE 'ab%de' } 1
          904  +do_execsql_test e_expr-14.2.3 { SELECT 'abABCde' LIKE 'ab%de' } 1
          905  +
          906  +# EVIDENCE-OF: R-30433-25443 An underscore ("_") in the LIKE pattern
          907  +# matches any single character in the string.
          908  +#
          909  +do_execsql_test e_expr-14.3.1 { SELECT 'abde'    LIKE 'ab_de' } 0
          910  +do_execsql_test e_expr-14.3.2 { SELECT 'abXde'   LIKE 'ab_de' } 1
          911  +do_execsql_test e_expr-14.3.3 { SELECT 'abABCde' LIKE 'ab_de' } 0
          912  +
          913  +# EVIDENCE-OF: R-59007-20454 Any other character matches itself or its
          914  +# lower/upper case equivalent (i.e. case-insensitive matching).
          915  +#
          916  +do_execsql_test e_expr-14.4.1 { SELECT 'abc' LIKE 'aBc' } 1
          917  +do_execsql_test e_expr-14.4.2 { SELECT 'aBc' LIKE 'aBc' } 1
          918  +do_execsql_test e_expr-14.4.3 { SELECT 'ac'  LIKE 'aBc' } 0
          919  +
          920  +# EVIDENCE-OF: R-23648-58527 SQLite only understands upper/lower case
          921  +# for ASCII characters by default.
          922  +#
          923  +# EVIDENCE-OF: R-04532-11527 The LIKE operator is case sensitive by
          924  +# default for unicode characters that are beyond the ASCII range.
          925  +#
          926  +# EVIDENCE-OF: R-44381-11669 the expression
          927  +# 'a'&nbsp;LIKE&nbsp;'A' is TRUE but
          928  +# '&aelig;'&nbsp;LIKE&nbsp;'&AElig;' is FALSE.
          929  +#
          930  +do_execsql_test e_expr-14.5.1 { SELECT 'A' LIKE 'a'         } 1
          931  +do_execsql_test e_expr-14.5.2 "SELECT '\u00c6' LIKE '\u00e6'" 0
          932  +
          933  +# EVIDENCE-OF: R-56683-13731 If the optional ESCAPE clause is present,
          934  +# then the expression following the ESCAPE keyword must evaluate to a
          935  +# string consisting of a single character.
          936  +#
          937  +do_catchsql_test e_expr-14.6.1 { 
          938  +  SELECT 'A' LIKE 'a' ESCAPE '12' 
          939  +} {1 {ESCAPE expression must be a single character}}
          940  +do_catchsql_test e_expr-14.6.2 { 
          941  +  SELECT 'A' LIKE 'a' ESCAPE '' 
          942  +} {1 {ESCAPE expression must be a single character}}
          943  +do_catchsql_test e_expr-14.6.3 { SELECT 'A' LIKE 'a' ESCAPE 'x' }    {0 1}
          944  +do_catchsql_test e_expr-14.6.4 "SELECT 'A' LIKE 'a' ESCAPE '\u00e6'" {0 1}
          945  +
          946  +# EVIDENCE-OF: R-02045-23762 This character may be used in the LIKE
          947  +# pattern to include literal percent or underscore characters.
          948  +#
          949  +# EVIDENCE-OF: R-13345-31830 The escape character followed by a percent
          950  +# symbol (%), underscore (_), or a second instance of the escape
          951  +# character itself matches a literal percent symbol, underscore, or a
          952  +# single escape character, respectively.
          953  +#
          954  +do_execsql_test e_expr-14.7.1  { SELECT 'abc%'  LIKE 'abcX%' ESCAPE 'X' } 1
          955  +do_execsql_test e_expr-14.7.2  { SELECT 'abc5'  LIKE 'abcX%' ESCAPE 'X' } 0
          956  +do_execsql_test e_expr-14.7.3  { SELECT 'abc'   LIKE 'abcX%' ESCAPE 'X' } 0
          957  +do_execsql_test e_expr-14.7.4  { SELECT 'abcX%' LIKE 'abcX%' ESCAPE 'X' } 0
          958  +do_execsql_test e_expr-14.7.5  { SELECT 'abc%%' LIKE 'abcX%' ESCAPE 'X' } 0
          959  +
          960  +do_execsql_test e_expr-14.7.6  { SELECT 'abc_'  LIKE 'abcX_' ESCAPE 'X' } 1
          961  +do_execsql_test e_expr-14.7.7  { SELECT 'abc5'  LIKE 'abcX_' ESCAPE 'X' } 0
          962  +do_execsql_test e_expr-14.7.8  { SELECT 'abc'   LIKE 'abcX_' ESCAPE 'X' } 0
          963  +do_execsql_test e_expr-14.7.9  { SELECT 'abcX_' LIKE 'abcX_' ESCAPE 'X' } 0
          964  +do_execsql_test e_expr-14.7.10 { SELECT 'abc__' LIKE 'abcX_' ESCAPE 'X' } 0
          965  +
          966  +do_execsql_test e_expr-14.7.11 { SELECT 'abcX'  LIKE 'abcXX' ESCAPE 'X' } 1
          967  +do_execsql_test e_expr-14.7.12 { SELECT 'abc5'  LIKE 'abcXX' ESCAPE 'X' } 0
          968  +do_execsql_test e_expr-14.7.13 { SELECT 'abc'   LIKE 'abcXX' ESCAPE 'X' } 0
          969  +do_execsql_test e_expr-14.7.14 { SELECT 'abcXX' LIKE 'abcXX' ESCAPE 'X' } 0
          970  +
          971  +# EVIDENCE-OF: R-51359-17496 The infix LIKE operator is implemented by
          972  +# calling the application-defined SQL functions like(Y,X) or like(Y,X,Z).
          973  +#
          974  +proc likefunc {args} {
          975  +  eval lappend ::likeargs $args
          976  +  return 1
          977  +}
          978  +db func like likefunc
          979  +set ::likeargs [list]
          980  +do_execsql_test e_expr-15.1.1 { SELECT 'abc' LIKE 'def' } 1
          981  +do_test         e_expr-15.1.2 { set likeargs } {def abc}
          982  +set ::likeargs [list]
          983  +do_execsql_test e_expr-15.1.3 { SELECT 'abc' LIKE 'def' ESCAPE 'X' } 1
          984  +do_test         e_expr-15.1.4 { set likeargs } {def abc X}
          985  +db close
          986  +sqlite3 db test.db
          987  +
          988  +# EVIDENCE-OF: R-22868-25880 The LIKE operator can be made case
          989  +# sensitive using the case_sensitive_like pragma.
          990  +#
          991  +do_execsql_test e_expr-16.1.1 { SELECT 'abcxyz' LIKE 'ABC%' } 1
          992  +do_execsql_test e_expr-16.1.2 { PRAGMA case_sensitive_like = 1 } {}
          993  +do_execsql_test e_expr-16.1.3 { SELECT 'abcxyz' LIKE 'ABC%' } 0
          994  +do_execsql_test e_expr-16.1.4 { SELECT 'ABCxyz' LIKE 'ABC%' } 1
          995  +do_execsql_test e_expr-16.1.5 { PRAGMA case_sensitive_like = 0 } {}
          996  +do_execsql_test e_expr-16.1.6 { SELECT 'abcxyz' LIKE 'ABC%' } 1
          997  +do_execsql_test e_expr-16.1.7 { SELECT 'ABCxyz' LIKE 'ABC%' } 1
          998  +
          999  +# EVIDENCE-OF: R-52087-12043 The GLOB operator is similar to LIKE but
         1000  +# uses the Unix file globbing syntax for its wildcards.
         1001  +#
         1002  +# EVIDENCE-OF: R-09813-17279 Also, GLOB is case sensitive, unlike LIKE.
         1003  +#
         1004  +do_execsql_test e_expr-17.1.1 { SELECT 'abcxyz' GLOB 'abc%' } 0
         1005  +do_execsql_test e_expr-17.1.2 { SELECT 'abcxyz' GLOB 'abc*' } 1
         1006  +do_execsql_test e_expr-17.1.3 { SELECT 'abcxyz' GLOB 'abc___' } 0
         1007  +do_execsql_test e_expr-17.1.4 { SELECT 'abcxyz' GLOB 'abc???' } 1
         1008  +
         1009  +do_execsql_test e_expr-17.1.5 { SELECT 'abcxyz' GLOB 'abc*' } 1
         1010  +do_execsql_test e_expr-17.1.6 { SELECT 'ABCxyz' GLOB 'abc*' } 0
         1011  +do_execsql_test e_expr-17.1.7 { SELECT 'abcxyz' GLOB 'ABC*' } 0
         1012  +
         1013  +# EVIDENCE-OF: R-39616-20555 Both GLOB and LIKE may be preceded by the
         1014  +# NOT keyword to invert the sense of the test.
         1015  +#
         1016  +do_execsql_test e_expr-17.2.1 { SELECT 'abcxyz' NOT GLOB 'ABC*' } 1
         1017  +do_execsql_test e_expr-17.2.2 { SELECT 'abcxyz' NOT GLOB 'abc*' } 0
         1018  +do_execsql_test e_expr-17.2.3 { SELECT 'abcxyz' NOT LIKE 'ABC%' } 0
         1019  +do_execsql_test e_expr-17.2.4 { SELECT 'abcxyz' NOT LIKE 'abc%' } 0
         1020  +do_execsql_test e_expr-17.2.5 { SELECT 'abdxyz' NOT LIKE 'abc%' } 1
         1021  +
         1022  +db nullvalue null
         1023  +do_execsql_test e_expr-17.2.6 { SELECT 'abcxyz' NOT GLOB NULL } null
         1024  +do_execsql_test e_expr-17.2.7 { SELECT 'abcxyz' NOT LIKE NULL } null
         1025  +do_execsql_test e_expr-17.2.8 { SELECT NULL NOT GLOB 'abc*' } null
         1026  +do_execsql_test e_expr-17.2.9 { SELECT NULL NOT LIKE 'ABC%' } null
         1027  +db nullvalue {}
         1028  +
         1029  +# EVIDENCE-OF: R-39414-35489 The infix GLOB operator is implemented by
         1030  +# calling the function glob(Y,X) and can be modified by overriding that
         1031  +# function.
         1032  +proc globfunc {args} {
         1033  +  eval lappend ::globargs $args
         1034  +  return 1
         1035  +}
         1036  +db func glob -argcount 2 globfunc
         1037  +set ::globargs [list]
         1038  +do_execsql_test e_expr-17.3.1 { SELECT 'abc' GLOB 'def' } 1
         1039  +do_test         e_expr-17.3.2 { set globargs } {def abc}
         1040  +set ::globargs [list]
         1041  +do_execsql_test e_expr-17.3.3 { SELECT 'X' NOT GLOB 'Y' } 0
         1042  +do_test         e_expr-17.3.4 { set globargs } {Y X}
         1043  +sqlite3 db test.db
         1044  +
         1045  +# EVIDENCE-OF: R-41650-20872 No regexp() user function is defined by
         1046  +# default and so use of the REGEXP operator will normally result in an
         1047  +# error message.
         1048  +#
         1049  +do_catchsql_test e_expr-18.1.1 { 
         1050  +  SELECT regexp('abc', 'def') 
         1051  +} {1 {no such function: regexp}}
         1052  +do_catchsql_test e_expr-18.1.2 { 
         1053  +  SELECT 'abc' REGEXP 'def'
         1054  +} {1 {no such function: REGEXP}}
         1055  +
         1056  +# EVIDENCE-OF: R-33693-50180 The REGEXP operator is a special syntax for
         1057  +# the regexp() user function.
         1058  +#
         1059  +# EVIDENCE-OF: R-57289-13578 If a application-defined SQL function named
         1060  +# "regexp" is added at run-time, that function will be called in order
         1061  +# to implement the REGEXP operator.
         1062  +#
         1063  +proc regexpfunc {args} {
         1064  +  eval lappend ::regexpargs $args
         1065  +  return 1
         1066  +}
         1067  +db func regexp -argcount 2 regexpfunc
         1068  +set ::regexpargs [list]
         1069  +do_execsql_test e_expr-18.2.1 { SELECT 'abc' REGEXP 'def' } 1
         1070  +do_test         e_expr-18.2.2 { set regexpargs } {def abc}
         1071  +set ::regexpargs [list]
         1072  +do_execsql_test e_expr-18.2.3 { SELECT 'X' NOT REGEXP 'Y' } 0
         1073  +do_test         e_expr-18.2.4 { set regexpargs } {Y X}
         1074  +sqlite3 db test.db
   871   1075   
   872         -do_execsql_test e_expr-13.2.19  { SELECT 0 AND 0 BETWEEN 0 AND 1   } 0
   873         -do_execsql_test e_expr-13.2.20  { SELECT 0 AND (0 BETWEEN 0 AND 1) } 0
   874         -do_execsql_test e_expr-13.2.21  { SELECT (0 AND 0) BETWEEN 0 AND 1 } 1
   875         -do_execsql_test e_expr-13.2.22  { SELECT 0 BETWEEN -1 AND 1 AND 0   } 0
   876         -do_execsql_test e_expr-13.2.23  { SELECT (0 BETWEEN -1 AND 1) AND 0 } 0
   877         -do_execsql_test e_expr-13.2.24  { SELECT 0 BETWEEN -1 AND (1 AND 0) } 1
         1076  +# EVIDENCE-OF: R-42037-37826 The default match() function implementation
         1077  +# raises an exception and is not really useful for anything.
         1078  +#
         1079  +do_catchsql_test e_expr-19.1.1 { 
         1080  +  SELECT 'abc' MATCH 'def' 
         1081  +} {1 {unable to use function MATCH in the requested context}}
         1082  +do_catchsql_test e_expr-19.1.2 { 
         1083  +  SELECT match('abc', 'def')
         1084  +} {1 {unable to use function MATCH in the requested context}}
   878   1085   
   879         -do_execsql_test e_expr-13.2.25  { SELECT 2 < 3 BETWEEN 0 AND 1   } 1
   880         -do_execsql_test e_expr-13.2.26  { SELECT (2 < 3) BETWEEN 0 AND 1 } 1
   881         -do_execsql_test e_expr-13.2.27  { SELECT 2 < (3 BETWEEN 0 AND 1) } 0
   882         -do_execsql_test e_expr-13.2.28  { SELECT 2 BETWEEN 1 AND 2 < 3    } 0
   883         -do_execsql_test e_expr-13.2.29  { SELECT 2 BETWEEN 1 AND (2 < 3)  } 0
   884         -do_execsql_test e_expr-13.2.30  { SELECT (2 BETWEEN 1 AND 2) < 3  } 1
         1086  +# EVIDENCE-OF: R-37916-47407 The MATCH operator is a special syntax for
         1087  +# the match() application-defined function.
         1088  +#
         1089  +# EVIDENCE-OF: R-06021-09373 But extensions can override the match()
         1090  +# function with more helpful logic.
         1091  +#
         1092  +proc matchfunc {args} {
         1093  +  eval lappend ::matchargs $args
         1094  +  return 1
         1095  +}
         1096  +db func match -argcount 2 matchfunc
         1097  +set ::matchargs [list]
         1098  +do_execsql_test e_expr-19.2.1 { SELECT 'abc' MATCH 'def' } 1
         1099  +do_test         e_expr-19.2.2 { set matchargs } {def abc}
         1100  +set ::matchargs [list]
         1101  +do_execsql_test e_expr-19.2.3 { SELECT 'X' NOT MATCH 'Y' } 0
         1102  +do_test         e_expr-19.2.4 { set matchargs } {Y X}
         1103  +sqlite3 db test.db
         1104  +
   885   1105   
   886   1106   finish_test

Changes to test/ioerr5.test.

   125    125       # from UTF-16 text. To do this, SQLite will need to reclaim memory
   126    126       # from the pager that is in error state. Including that associated
   127    127       # with the dirty page.
   128    128       #
   129    129       do_test ioerr5-1.$locking_mode-$iFail.3 {
   130    130         sqlite3_soft_heap_limit 1024
   131    131         compilesql16 "SELECT 10"
   132         -    } {}
          132  +    } {SQLITE_OK}
   133    133   
   134    134       close $channel
   135    135   
   136    136       # Ensure that nothing was written to the database while reclaiming
   137    137       # memory from the pager in error state.
   138    138       #
   139    139       do_test ioerr5-1.$locking_mode-$iFail.4 {

Changes to test/lock_common.tcl.

    61     61     }
    62     62   }
    63     63   
    64     64   # Launch another testfixture process to be controlled by this one. A
    65     65   # channel name is returned that may be passed as the first argument to proc
    66     66   # 'testfixture' to execute a command. The child testfixture process is shut
    67     67   # down by closing the channel.
    68         -proc launch_testfixture {} {
           68  +proc launch_testfixture {{prg ""}} {
    69     69     write_main_loop
    70         -  set prg [info nameofexec]
    71         -  if {$prg eq ""} {
    72         -    set prg [file join . testfixture]
    73         -  }
           70  +  if {$prg eq ""} { set prg [info nameofexec] }
           71  +  if {$prg eq ""} { set prg testfixture }
           72  +  if {[file tail $prg]==$prg} { set prg [file join . $prg] }
    74     73     set chan [open "|$prg tf_main.tcl" r+]
    75     74     fconfigure $chan -buffering line
    76         -  testfixture $chan "sqlite3_test_control_pending_byte $::sqlite_pending_byte"
           75  +  set rc [catch { 
           76  +    testfixture $chan "sqlite3_test_control_pending_byte $::sqlite_pending_byte"
           77  +  }]
           78  +  if {$rc} {
           79  +    testfixture $chan "set ::sqlite_pending_byte $::sqlite_pending_byte"
           80  +  }
    77     81     return $chan
    78     82   }
    79     83   
    80     84   # Execute a command in a child testfixture process, connected by two-way
    81     85   # channel $chan. Return the result of the command, or an error message.
    82     86   #
    83     87   proc testfixture {chan cmd} {

Changes to test/pagerfault.test.

    48     48     faultsim_save_and_close
    49     49   } {}
    50     50   do_faultsim_test pagerfault-1 -prep {
    51     51     faultsim_restore_and_reopen
    52     52   } -body {
    53     53     execsql { SELECT count(*) FROM t1 }
    54     54   } -test {
    55         -  faultsim_test_result {0 4}
           55  +  faultsim_test_result {0 4} 
    56     56     faultsim_integrity_check
    57     57     if {[db one { SELECT count(*) FROM t1 }] != 4} {
    58     58       error "Database content appears incorrect"
    59     59     }
    60     60   }
    61     61   
    62     62   #-------------------------------------------------------------------------
................................................................................
  1225   1225       error "Expected file size to be 3072 or 12288 bytes - actual size $sz bytes"
  1226   1226     }
  1227   1227     if {$testrc==0 && $sz!=4096*3} { 
  1228   1228       error "Expected file size to be 12288 bytes - actual size $sz bytes"
  1229   1229     }
  1230   1230   } 
  1231   1231   
         1232  +do_test pagerfault-27-pre {
         1233  +  faultsim_delete_and_reopen
         1234  +  db func a_string a_string
         1235  +  execsql {
         1236  +    PRAGMA page_size = 1024;
         1237  +    CREATE TABLE t1(a, b);
         1238  +    CREATE TABLE t2(a UNIQUE, b UNIQUE);
         1239  +    INSERT INTO t2 VALUES( a_string(800), a_string(800) );
         1240  +    INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1241  +    INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1242  +    INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1243  +    INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1244  +    INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1245  +    INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1246  +    INSERT INTO t1 VALUES (a_string(20000), a_string(20000));
         1247  +  }
         1248  +  faultsim_save_and_close
         1249  +} {}
         1250  +do_faultsim_test pagerfault-27 -faults ioerr-persistent -prep {
         1251  +  faultsim_restore_and_reopen
         1252  +  db func a_string a_string
         1253  +  execsql { 
         1254  +    PRAGMA cache_size = 10;
         1255  +    BEGIN EXCLUSIVE;
         1256  +  }
         1257  +  set ::channel [db incrblob t1 a 1]
         1258  +} -body {
         1259  +  puts $::channel [string repeat abc 6000]
         1260  +  flush $::channel
         1261  +} -test {
         1262  +  catchsql { UPDATE t2 SET a = a_string(800), b = a_string(800) }
         1263  +  catch { close $::channel }
         1264  +  catchsql { ROLLBACK }
         1265  +  faultsim_integrity_check
         1266  +}
  1232   1267   
  1233   1268   finish_test
         1269  +

Added test/tkt-5e10420e8d.test.

            1  +# 2010 August 23
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +set testdir [file dirname $argv0]
           14  +source $testdir/tester.tcl
           15  +
           16  +do_execsql_test tkt-5e10420e8d.1 {
           17  +  PRAGMA page_size = 1024;
           18  +  PRAGMA auto_vacuum = incremental;
           19  +
           20  +  CREATE TABLE t1(x);
           21  +  CREATE TABLE t2(x);
           22  +  CREATE TABLE t3(x);
           23  +} {}
           24  +
           25  +do_execsql_test tkt-5e10420e8d.2 {
           26  +  INSERT INTO t3 VALUES(randomblob(500 + 1024*248));
           27  +  INSERT INTO t1 VALUES(randomblob(1500));
           28  +  INSERT INTO t2 VALUES(randomblob(500 + 1024*248));
           29  +
           30  +  DELETE FROM t3;
           31  +  DELETE FROM t2;
           32  +  DELETE FROM t1;
           33  +} {}
           34  +
           35  +do_execsql_test tkt-5e10420e8d.3 {
           36  +  PRAGMA incremental_vacuum(248)
           37  +} {}
           38  +
           39  +do_execsql_test tkt-5e10420e8d.4 {
           40  +  PRAGMA incremental_vacuum(1)
           41  +} {}
           42  +
           43  +db close
           44  +sqlite3 db test.db
           45  +
           46  +do_execsql_test tkt-5e10420e8d.5 {
           47  +  PRAGMA integrity_check;
           48  +} {ok}
           49  +
           50  +finish_test

Changes to test/wal.test.

  1472   1472     }]
  1473   1473   }
  1474   1474   
  1475   1475   #-------------------------------------------------------------------------
  1476   1476   # Test that when 1 or more pages are recovered from a WAL file, 
  1477   1477   # sqlite3_log() is invoked to report this to the user.
  1478   1478   #
  1479         -set walfile [file join [pwd] test.db-wal]
         1479  +set walfile [file nativename [file join [pwd] test.db-wal]]
  1480   1480   catch {db close}
  1481   1481   file delete -force test.db
  1482   1482   do_test wal-23.1 {
  1483   1483     faultsim_delete_and_reopen
  1484   1484     execsql {
  1485   1485       CREATE TABLE t1(a, b);
  1486   1486       PRAGMA journal_mode = WAL;
................................................................................
  1499   1499   
  1500   1500   do_test wal-23.3 {
  1501   1501     db close
  1502   1502     set ::log [list]
  1503   1503     faultsim_restore_and_reopen
  1504   1504     execsql { SELECT * FROM t1 }
  1505   1505   } {1 2 3 4}
         1506  +set nPage [expr 2+$AUTOVACUUM]
  1506   1507   do_test wal-23.4 { 
  1507   1508     set ::log 
  1508         -} [list SQLITE_OK "Recovered 2 frames from WAL file $walfile"]
         1509  +} [list SQLITE_OK "Recovered $nPage frames from WAL file $walfile"]
  1509   1510   
  1510   1511   db close
  1511   1512   sqlite3_shutdown
  1512   1513   test_sqlite3_log
  1513   1514   sqlite3_initialize
  1514   1515   
  1515   1516   finish_test

Changes to tool/shell4.test.

     6      6   #    May you do good and not evil.
     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   #
    12     12   # The focus of this file is testing the CLI shell tool.
           13  +# These tests are specific to the .stats command.
    13     14   #
    14     15   # $Id: shell4.test,v 1.7 2009/07/17 16:54:48 shaneh Exp $
    15     16   #
    16     17   
    17     18   # Test plan:
    18     19   #
    19     20   #   shell4-1.*: Basic tests specific to the "stats" command.
    20     21   #
    21     22   
    22         -package require sqlite3
    23         -
    24     23   set CLI "./sqlite3"
    25     24   
    26     25   proc do_test {name cmd expected} {
    27     26     puts -nonewline "$name ..."
    28     27     set res [uplevel $cmd]
    29     28     if {$res eq $expected} {
    30     29       puts Ok
................................................................................
    32     31       puts Error
    33     32       puts "  Got: $res"
    34     33       puts "  Expected: $expected"
    35     34       exit
    36     35     }
    37     36   }
    38     37   
    39         -proc execsql {sql} {
    40         -  uplevel [list db eval $sql]
    41         -}
    42         -
    43         -proc catchsql {sql} {
    44         -  set rc [catch {uplevel [list db eval $sql]} msg]
    45         -  list $rc $msg
    46         -}
    47         -
    48     38   proc catchcmd {db {cmd ""}} {
    49     39     global CLI
    50     40     set out [open cmds.txt w]
    51     41     puts $out $cmd
    52     42     close $out
    53     43     set line "exec $CLI $db < cmds.txt"
    54     44     set rc [catch { eval $line } msg]
    55     45     list $rc $msg
    56     46   }
    57     47   
    58     48   file delete -force test.db test.db.journal
    59         -sqlite3 db test.db
    60     49   
    61     50   #----------------------------------------------------------------------------
    62     51   # Test cases shell4-1.*: Tests specific to the "stats" command.
    63     52   #
    64     53   
    65     54   # should default to off
    66     55   do_test shell4-1.1.1 {

Added tool/shell5.test.

            1  +# 2010 August 4
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# The focus of this file is testing the CLI shell tool.
           13  +# These tests are specific to the .import command.
           14  +#
           15  +# $Id: shell5.test,v 1.7 2009/07/17 16:54:48 shaneh Exp $
           16  +#
           17  +
           18  +# Test plan:
           19  +#
           20  +#   shell5-1.*: Basic tests specific to the ".import" command.
           21  +#
           22  +
           23  +set CLI "./sqlite3"
           24  +
           25  +proc do_test {name cmd expected} {
           26  +  puts -nonewline "$name ..."
           27  +  set res [uplevel $cmd]
           28  +  if {$res eq $expected} {
           29  +    puts Ok
           30  +  } else {
           31  +    puts Error
           32  +    puts "  Got: $res"
           33  +    puts "  Expected: $expected"
           34  +    exit
           35  +  }
           36  +}
           37  +
           38  +proc catchcmd {db {cmd ""}} {
           39  +  global CLI
           40  +  set out [open cmds.txt w]
           41  +  puts $out $cmd
           42  +  close $out
           43  +  set line "exec $CLI $db < cmds.txt"
           44  +  set rc [catch { eval $line } msg]
           45  +  list $rc $msg
           46  +}
           47  +
           48  +file delete -force test.db test.db.journal
           49  +
           50  +#----------------------------------------------------------------------------
           51  +# Test cases shell5-1.*: Basic handling of the .import and .separator commands.
           52  +#
           53  +
           54  +# .import FILE TABLE     Import data from FILE into TABLE
           55  +do_test shell5-1.1.1 {
           56  +  catchcmd "test.db" ".import"
           57  +} {1 {Error: unknown command or invalid arguments:  "import". Enter ".help" for help}}
           58  +do_test shell5-1.1.2 {
           59  +  catchcmd "test.db" ".import FOO"
           60  +} {1 {Error: unknown command or invalid arguments:  "import". Enter ".help" for help}}
           61  +do_test shell5-1.1.2 {
           62  +  catchcmd "test.db" ".import FOO BAR"
           63  +} {1 {Error: no such table: BAR}}
           64  +do_test shell5-1.1.3 {
           65  +  # too many arguments
           66  +  catchcmd "test.db" ".import FOO BAR BAD"
           67  +} {1 {Error: unknown command or invalid arguments:  "import". Enter ".help" for help}}
           68  +
           69  +# .separator STRING      Change separator used by output mode and .import
           70  +do_test shell1-1.2.1 {
           71  +  catchcmd "test.db" ".separator"
           72  +} {1 {Error: unknown command or invalid arguments:  "separator". Enter ".help" for help}}
           73  +do_test shell1-1.2.2 {
           74  +  catchcmd "test.db" ".separator FOO"
           75  +} {0 {}}
           76  +do_test shell1-1.2.3 {
           77  +  # too many arguments
           78  +  catchcmd "test.db" ".separator FOO BAD"
           79  +} {1 {Error: unknown command or invalid arguments:  "separator". Enter ".help" for help}}
           80  +
           81  +# separator should default to "|"
           82  +do_test shell5-1.3.1 {
           83  +  set res [catchcmd "test.db" ".show"]
           84  +  list [regexp {separator: \"\|\"} $res]
           85  +} {1}
           86  +
           87  +# set separator to different value.
           88  +# check that .show reports new value
           89  +do_test shell5-1.3.2 {
           90  +  set res [catchcmd "test.db" {.separator ,
           91  +.show}]
           92  +  list [regexp {separator: \",\"} $res]
           93  +} {1}
           94  +
           95  +# import file doesn't exist
           96  +do_test shell5-1.4.1 {
           97  +  file delete -force FOO
           98  +  set res [catchcmd "test.db" {CREATE TABLE t1(a, b);
           99  +.import FOO t1}]
          100  +} {1 {Error: cannot open "FOO"}}
          101  +
          102  +# empty import file
          103  +do_test shell5-1.4.2 {
          104  +  file delete -force shell5.csv
          105  +  set in [open shell5.csv w]
          106  +  close $in
          107  +  set res [catchcmd "test.db" {.import shell5.csv t1
          108  +SELECT COUNT(*) FROM t1;}]
          109  +} {0 0}
          110  +
          111  +# import file with 1 row, 1 column (expecting 2 cols)
          112  +do_test shell5-1.4.3 {
          113  +  set in [open shell5.csv w]
          114  +  puts $in "1"
          115  +  close $in
          116  +  set res [catchcmd "test.db" {.import shell5.csv t1}]
          117  +} {1 {Error: shell5.csv line 1: expected 2 columns of data but found 1}}
          118  +
          119  +# import file with 1 row, 3 columns (expecting 2 cols)
          120  +do_test shell5-1.4.4 {
          121  +  set in [open shell5.csv w]
          122  +  puts $in "1|2|3"
          123  +  close $in
          124  +  set res [catchcmd "test.db" {.import shell5.csv t1}]
          125  +} {1 {Error: shell5.csv line 1: expected 2 columns of data but found 3}}
          126  +
          127  +# import file with 1 row, 2 columns
          128  +do_test shell5-1.4.5 {
          129  +  set in [open shell5.csv w]
          130  +  puts $in "1|2"
          131  +  close $in
          132  +  set res [catchcmd "test.db" {.import shell5.csv t1
          133  +SELECT COUNT(*) FROM t1;}]
          134  +} {0 1}
          135  +
          136  +# import file with 2 rows, 2 columns
          137  +# note we end up with 3 rows because of the 1 row 
          138  +# imported above.
          139  +do_test shell5-1.4.6 {
          140  +  set in [open shell5.csv w]
          141  +  puts $in "2|3"
          142  +  puts $in "3|4"
          143  +  close $in
          144  +  set res [catchcmd "test.db" {.import shell5.csv t1
          145  +SELECT COUNT(*) FROM t1;}]
          146  +} {0 3}
          147  +
          148  +# import file with 1 row, 2 columns, using a comma
          149  +do_test shell5-1.4.7 {
          150  +  set in [open shell5.csv w]
          151  +  puts $in "4,5"
          152  +  close $in
          153  +  set res [catchcmd "test.db" {.separator ,
          154  +.import shell5.csv t1
          155  +SELECT COUNT(*) FROM t1;}]
          156  +} {0 4}
          157  +
          158  +# import file with 1 row, 2 columns, text data
          159  +do_test shell5-1.4.8.1 {
          160  +  set in [open shell5.csv w]
          161  +  puts $in "5|Now is the time for all good men to come to the aid of their country."
          162  +  close $in
          163  +  set res [catchcmd "test.db" {.import shell5.csv t1
          164  +SELECT COUNT(*) FROM t1;}]
          165  +} {0 5}
          166  +
          167  +do_test shell5-1.4.8.2 {
          168  +  catchcmd "test.db" {SELECT b FROM t1 WHERE a='5';}
          169  +} {0 {Now is the time for all good men to come to the aid of their country.}}
          170  +
          171  +# import file with 1 row, 2 columns, quoted text data
          172  +# note that currently sqlite doesn't support quoted fields, and
          173  +# imports the entire field, quotes and all.
          174  +do_test shell5-1.4.9.1 {
          175  +  set in [open shell5.csv w]
          176  +  puts $in "6|'Now is the time for all good men to come to the aid of their country.'"
          177  +  close $in
          178  +  set res [catchcmd "test.db" {.import shell5.csv t1
          179  +SELECT COUNT(*) FROM t1;}]
          180  +} {0 6}
          181  +
          182  +do_test shell5-1.4.9.2 {
          183  +  catchcmd "test.db" {SELECT b FROM t1 WHERE a='6';}
          184  +} {0 {'Now is the time for all good men to come to the aid of their country.'}}
          185  +
          186  +# import file with 1 row, 2 columns, quoted text data
          187  +do_test shell5-1.4.10.1 {
          188  +  set in [open shell5.csv w]
          189  +  puts $in "7|\"Now is the time for all good men to come to the aid of their country.\""
          190  +  close $in
          191  +  set res [catchcmd "test.db" {.import shell5.csv t1
          192  +SELECT COUNT(*) FROM t1;}]
          193  +} {0 7}
          194  +
          195  +do_test shell5-1.4.10.2 {
          196  +  catchcmd "test.db" {SELECT b FROM t1 WHERE a='7';}
          197  +} {0 {"Now is the time for all good men to come to the aid of their country."}}
          198  +
          199  +# check importing very long field
          200  +do_test shell5-1.5.1 {
          201  +  set str [string repeat X 999]
          202  +  set in [open shell5.csv w]
          203  +  puts $in "8|$str"
          204  +  close $in
          205  +  set res [catchcmd "test.db" {.import shell5.csv t1
          206  +SELECT length(b) FROM t1 WHERE a='8';}]
          207  +} {0 999}
          208  +
          209  +# try importing into a table with a large number of columns.
          210  +# This is limited by SQLITE_MAX_VARIABLE_NUMBER, which defaults to 999.
          211  +set cols 999
          212  +do_test shell5-1.6.1 {
          213  +  set sql {CREATE TABLE t2(}
          214  +  set data {}
          215  +  for {set i 1} {$i<$cols} {incr i} {
          216  +    append sql "c$i,"
          217  +    append data "$i|"
          218  +  }
          219  +  append sql "c$cols);"
          220  +  append data "$cols"
          221  +  catchcmd "test.db" $sql
          222  +  set in [open shell5.csv w]
          223  +  puts $in $data
          224  +  close $in
          225  +  set res [catchcmd "test.db" {.import shell5.csv t2
          226  +SELECT COUNT(*) FROM t2;}]
          227  +} {0 1}
          228  +
          229  +# try importing a large number of rows
          230  +set rows 999999
          231  +do_test shell5-1.7.1 {
          232  +  set in [open shell5.csv w]
          233  +  for {set i 1} {$i<=$rows} {incr i} {
          234  +    puts $in $i
          235  +  }
          236  +  close $in
          237  +  set res [catchcmd "test.db" {CREATE TABLE t3(a);
          238  +.import shell5.csv t3
          239  +SELECT COUNT(*) FROM t3;}]
          240  +} [list 0 $rows]
          241  +
          242  +
          243  +puts "CLI tests completed successfully"

Changes to tool/showdb.c.

    30     30       v = (v<<7) + (z[i]&0x7f);
    31     31       if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; }
    32     32     }
    33     33     v = (v<<8) + (z[i]&0xff);
    34     34     *pVal = v;
    35     35     return 9;
    36     36   }
           37  +
           38  +/*
           39  +** Extract a big-endian 32-bit integer
           40  +*/
           41  +static unsigned int decodeInt32(const unsigned char *z){
           42  +  return (z[0]<<24) + (z[1]<<16) + (z[2]<<8) + z[3];
           43  +}
    37     44   
    38     45   /* Report an out-of-memory error and die.
    39     46   */
    40     47   static void out_of_memory(void){
    41     48     fprintf(stderr,"Out of memory...\n");
    42     49     exit(1);
    43     50   }
................................................................................
   241    248       int cofst = iCellPtr + i*2;
   242    249       char *zDesc;
   243    250       cofst = a[cofst]*256 + a[cofst+1];
   244    251       describeCell(a[0], &a[cofst-hdrSize], &zDesc);
   245    252       printf(" %03x: cell[%d] %s\n", cofst, i, zDesc);
   246    253     }
   247    254   }
          255  +
          256  +/*
          257  +** Decode a freelist trunk page.
          258  +*/
          259  +static void decode_trunk_page(
          260  +  int pgno,             /* The page number */
          261  +  int pagesize,         /* Size of each page */
          262  +  int detail,           /* Show leaf pages if true */
          263  +  int recursive         /* Follow the trunk change if true */
          264  +){
          265  +  int n, i, k;
          266  +  unsigned char *a;
          267  +  while( pgno>0 ){
          268  +    a = getContent((pgno-1)*pagesize, pagesize);
          269  +    printf("Decode of freelist trunk page %d:\n", pgno);
          270  +    print_decode_line(a, 0, 4, "Next freelist trunk page");
          271  +    print_decode_line(a, 4, 4, "Number of entries on this page");
          272  +    if( detail ){
          273  +      n = (int)decodeInt32(&a[4]);
          274  +      for(i=0; i<n; i++){
          275  +        unsigned int x = decodeInt32(&a[8+4*i]);
          276  +        char zIdx[10];
          277  +        sprintf(zIdx, "[%d]", i);
          278  +        printf("  %5s %7u", zIdx, x);
          279  +        if( i%5==4 ) printf("\n");
          280  +      }
          281  +      if( i%5!=0 ) printf("\n");
          282  +    }
          283  +    if( !recursive ){
          284  +      pgno = 0;
          285  +    }else{
          286  +      pgno = (int)decodeInt32(&a[0]);
          287  +    }
          288  +    free(a);
          289  +  }
          290  +}
          291  +
          292  +/*
          293  +** Print a usage comment
          294  +*/
          295  +static void usage(const char *argv0){
          296  +  fprintf(stderr, "Usage %s FILENAME ?args...?\n\n", argv0);
          297  +  fprintf(stderr,
          298  +    "args:\n"
          299  +    "    dbheader        Show database header\n"
          300  +    "    NNN..MMM        Show hex of pages NNN through MMM\n"
          301  +    "    NNN..end        Show hex of pages NNN through end of file\n"
          302  +    "    NNNb            Decode btree page NNN\n"
          303  +    "    NNNt            Decode freelist trunk page NNN\n"
          304  +    "    NNNtd           Show leave freelist pages on the decode\n"
          305  +    "    NNNtr           Recurisvely decode freelist starting at NNN\n"
          306  +  );
          307  +}
   248    308   
   249    309   int main(int argc, char **argv){
   250    310     struct stat sbuf;
   251    311     unsigned char zPgSz[2];
   252    312     if( argc<2 ){
   253         -    fprintf(stderr,"Usage: %s FILENAME ?PAGE? ...\n", argv[0]);
          313  +    usage(argv[0]);
   254    314       exit(1);
   255    315     }
   256    316     db = open(argv[1], O_RDONLY);
   257    317     if( db<0 ){
   258    318       fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]);
   259    319       exit(1);
   260    320     }
   261    321     zPgSz[0] = 0;
   262    322     zPgSz[1] = 0;
   263    323     lseek(db, 16, SEEK_SET);
   264    324     read(db, zPgSz, 2);
   265         -  pagesize = zPgSz[0]*256 + zPgSz[1];
          325  +  pagesize = zPgSz[0]*256 + zPgSz[1]*65536;
   266    326     if( pagesize==0 ) pagesize = 1024;
   267    327     printf("Pagesize: %d\n", pagesize);
   268    328     fstat(db, &sbuf);
   269    329     mxPage = sbuf.st_size/pagesize;
   270    330     printf("Available pages: 1..%d\n", mxPage);
   271    331     if( argc==2 ){
   272    332       int i;
................................................................................
   300    360             ofst = (iStart-1)*pagesize;
   301    361             nByte = pagesize;
   302    362           }
   303    363           a = getContent(ofst, nByte);
   304    364           decode_btree_page(a, iStart, hdrSize);
   305    365           free(a);
   306    366           continue;
          367  +      }else if( zLeft && zLeft[0]=='t' ){
          368  +        unsigned char *a;
          369  +        int detail = 0;
          370  +        int recursive = 0;
          371  +        int i;
          372  +        for(i=1; zLeft[i]; i++){
          373  +          if( zLeft[i]=='r' ) recursive = 1;
          374  +          if( zLeft[i]=='d' ) detail = 1;
          375  +        }
          376  +        decode_trunk_page(iStart, pagesize, detail, recursive);
          377  +        continue;
   307    378         }else{
   308    379           iEnd = iStart;
   309    380         }
   310    381         if( iStart<1 || iEnd<iStart || iEnd>mxPage ){
   311    382           fprintf(stderr,
   312    383             "Page argument should be LOWER?..UPPER?.  Range 1 to %d\n",
   313    384             mxPage);