/ Check-in [ad5cd15f]
Login

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

Overview
Comment:Import all the latest trunk changes into the WinRT branch. Refactor and/or remove WinCE-specific macros and functions used for file locking to improve clarity of presentation.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | winrt
Files: files | file ages | folders
SHA1: ad5cd15f49b286896f94ab1ff207077beee40e12
User & Date: mistachkin 2012-04-18 05:57:38
Context
2012-04-18
10:29
Merge build tool updates from trunk. Also, modify MSVC makefile to allow for debugging of build tool issues. check-in: b2a2fdb0 user: mistachkin tags: winrt
05:57
Import all the latest trunk changes into the WinRT branch. Refactor and/or remove WinCE-specific macros and functions used for file locking to improve clarity of presentation. check-in: ad5cd15f user: mistachkin tags: winrt
2012-04-17
21:00
When compiling for WinRT, always use the 'appcontainer' linker option. check-in: 300bcfe3 user: mistachkin tags: winrt
16:38
Improved handling of aggregate subqueries within an aggregate query. check-in: 430bb59d user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

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 3.7.11.
            3  +# Generated by GNU Autoconf 2.62 for sqlite 3.7.12.
     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='3.7.11'
   747         -PACKAGE_STRING='sqlite 3.7.11'
          746  +PACKAGE_VERSION='3.7.12'
          747  +PACKAGE_STRING='sqlite 3.7.12'
   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>
................................................................................
  1481   1481   #
  1482   1482   # Report the --help message.
  1483   1483   #
  1484   1484   if test "$ac_init_help" = "long"; then
  1485   1485     # Omit some internal or obsolete options to make the list less imposing.
  1486   1486     # This message is too long to be a string in the A/UX 3.1 sh.
  1487   1487     cat <<_ACEOF
  1488         -\`configure' configures sqlite 3.7.11 to adapt to many kinds of systems.
         1488  +\`configure' configures sqlite 3.7.12 to adapt to many kinds of systems.
  1489   1489   
  1490   1490   Usage: $0 [OPTION]... [VAR=VALUE]...
  1491   1491   
  1492   1492   To assign environment variables (e.g., CC, CFLAGS...), specify them as
  1493   1493   VAR=VALUE.  See below for descriptions of some of the useful variables.
  1494   1494   
  1495   1495   Defaults for the options are specified in brackets.
................................................................................
  1546   1546     --build=BUILD     configure for building on BUILD [guessed]
  1547   1547     --host=HOST       cross-compile to build programs to run on HOST [BUILD]
  1548   1548   _ACEOF
  1549   1549   fi
  1550   1550   
  1551   1551   if test -n "$ac_init_help"; then
  1552   1552     case $ac_init_help in
  1553         -     short | recursive ) echo "Configuration of sqlite 3.7.11:";;
         1553  +     short | recursive ) echo "Configuration of sqlite 3.7.12:";;
  1554   1554      esac
  1555   1555     cat <<\_ACEOF
  1556   1556   
  1557   1557   Optional Features:
  1558   1558     --disable-option-checking  ignore unrecognized --enable/--with options
  1559   1559     --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  1560   1560     --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
................................................................................
  1662   1662       cd "$ac_pwd" || { ac_status=$?; break; }
  1663   1663     done
  1664   1664   fi
  1665   1665   
  1666   1666   test -n "$ac_init_help" && exit $ac_status
  1667   1667   if $ac_init_version; then
  1668   1668     cat <<\_ACEOF
  1669         -sqlite configure 3.7.11
         1669  +sqlite configure 3.7.12
  1670   1670   generated by GNU Autoconf 2.62
  1671   1671   
  1672   1672   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
  1673   1673   2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
  1674   1674   This configure script is free software; the Free Software Foundation
  1675   1675   gives unlimited permission to copy, distribute and modify it.
  1676   1676   _ACEOF
  1677   1677     exit
  1678   1678   fi
  1679   1679   cat >config.log <<_ACEOF
  1680   1680   This file contains any messages produced by compilers while
  1681   1681   running configure, to aid debugging if configure makes a mistake.
  1682   1682   
  1683         -It was created by sqlite $as_me 3.7.11, which was
         1683  +It was created by sqlite $as_me 3.7.12, which was
  1684   1684   generated by GNU Autoconf 2.62.  Invocation command line was
  1685   1685   
  1686   1686     $ $0 $@
  1687   1687   
  1688   1688   _ACEOF
  1689   1689   exec 5>>config.log
  1690   1690   {
................................................................................
 14028  14028   
 14029  14029   exec 6>&1
 14030  14030   
 14031  14031   # Save the log message, to keep $[0] and so on meaningful, and to
 14032  14032   # report actual input values of CONFIG_FILES etc. instead of their
 14033  14033   # values after options handling.
 14034  14034   ac_log="
 14035         -This file was extended by sqlite $as_me 3.7.11, which was
        14035  +This file was extended by sqlite $as_me 3.7.12, which was
 14036  14036   generated by GNU Autoconf 2.62.  Invocation command line was
 14037  14037   
 14038  14038     CONFIG_FILES    = $CONFIG_FILES
 14039  14039     CONFIG_HEADERS  = $CONFIG_HEADERS
 14040  14040     CONFIG_LINKS    = $CONFIG_LINKS
 14041  14041     CONFIG_COMMANDS = $CONFIG_COMMANDS
 14042  14042     $ $0 $@
................................................................................
 14081  14081   $config_commands
 14082  14082   
 14083  14083   Report bugs to <bug-autoconf@gnu.org>."
 14084  14084   
 14085  14085   _ACEOF
 14086  14086   cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 14087  14087   ac_cs_version="\\
 14088         -sqlite config.status 3.7.11
        14088  +sqlite config.status 3.7.12
 14089  14089   configured by $0, generated by GNU Autoconf 2.62,
 14090  14090     with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 14091  14091   
 14092  14092   Copyright (C) 2008 Free Software Foundation, Inc.
 14093  14093   This config.status script is free software; the Free Software Foundation
 14094  14094   gives unlimited permission to copy, distribute and modify it."
 14095  14095   

Changes to ext/fts3/fts3_icu.c.

   106    106   
   107    107     UChar32 c;
   108    108     int iInput = 0;
   109    109     int iOut = 0;
   110    110   
   111    111     *ppCursor = 0;
   112    112   
   113         -  if( nInput<0 ){
          113  +  if( zInput==0 ){
          114  +    nInput = 0;
          115  +    zInput = "";
          116  +  }else if( nInput<0 ){
   114    117       nInput = strlen(zInput);
   115    118     }
   116    119     nChar = nInput+1;
   117    120     pCsr = (IcuCursor *)sqlite3_malloc(
   118    121         sizeof(IcuCursor) +                /* IcuCursor */
   119    122         nChar * sizeof(UChar) +            /* IcuCursor.aChar[] */
   120    123         (nChar+1) * sizeof(int)            /* IcuCursor.aOffset[] */

Changes to ext/fts3/fts3_term.c.

    69     69     int nDb;                        /* Result of strlen(zDb) */
    70     70     int nFts3;                      /* Result of strlen(zFts3) */
    71     71     int nByte;                      /* Bytes of space to allocate here */
    72     72     int rc;                         /* value returned by declare_vtab() */
    73     73     Fts3termTable *p;                /* Virtual table object to return */
    74     74     int iIndex = 0;
    75     75   
           76  +  UNUSED_PARAMETER(pCtx);
    76     77     if( argc==5 ){
    77     78       iIndex = atoi(argv[4]);
    78     79       argc--;
    79     80     }
    80     81   
    81     82     /* The user should specify a single argument - the name of an fts3 table. */
    82     83     if( argc!=4 ){
................................................................................
   227    228       pCsr->pNext += sqlite3Fts3GetVarint(pCsr->pNext, &v);
   228    229       pCsr->iCol = 0;
   229    230       pCsr->iPos = 0;
   230    231     }
   231    232   
   232    233     if( v==1 ){
   233    234       pCsr->pNext += sqlite3Fts3GetVarint(pCsr->pNext, &v);
   234         -    pCsr->iCol += v;
          235  +    pCsr->iCol += (int)v;
   235    236       pCsr->iPos = 0;
   236    237       pCsr->pNext += sqlite3Fts3GetVarint(pCsr->pNext, &v);
   237    238     }
   238    239   
   239         -  pCsr->iPos += (v - 2);
          240  +  pCsr->iPos += (int)(v - 2);
   240    241   
   241    242     return SQLITE_OK;
   242    243   }
   243    244   
   244    245   /*
   245    246   ** xFilter - Initialize a cursor to point at the start of its data.
   246    247   */
................................................................................
   353    354        fts3termRowidMethod,         /* xRowid        */
   354    355        0,                           /* xUpdate       */
   355    356        0,                           /* xBegin        */
   356    357        0,                           /* xSync         */
   357    358        0,                           /* xCommit       */
   358    359        0,                           /* xRollback     */
   359    360        0,                           /* xFindFunction */
   360         -     0                            /* xRename       */
          361  +     0,                           /* xRename       */
          362  +     0,                           /* xSavepoint    */
          363  +     0,                           /* xRelease      */
          364  +     0                            /* xRollbackTo   */
   361    365     };
   362    366     int rc;                         /* Return code */
   363    367   
   364    368     rc = sqlite3_create_module(db, "fts4term", &fts3term_module, 0);
   365    369     return rc;
   366    370   }
   367    371   
   368    372   #endif
   369    373   #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */

Changes to ext/fts3/fts3_test.c.

    18     18   ** that the sqlite3_tokenizer_module.xLanguage() method is invoked correctly.
    19     19   */
    20     20   
    21     21   #include <tcl.h>
    22     22   #include <string.h>
    23     23   #include <assert.h>
    24     24   
    25         -#ifdef SQLITE_TEST
           25  +#if defined(SQLITE_TEST)
           26  +#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
    26     27   
    27     28   /* Required so that the "ifdef SQLITE_ENABLE_FTS3" below works */
    28     29   #include "fts3Int.h"
    29     30   
    30     31   #define NM_MAX_TOKEN 12
    31     32   
    32     33   typedef struct NearPhrase NearPhrase;
................................................................................
   156    157     NearDocument doc = {0, 0};
   157    158     Tcl_Obj **apDocToken;
   158    159     Tcl_Obj *pRet;
   159    160     Tcl_Obj *pPhrasecount = 0;
   160    161     
   161    162     Tcl_Obj **apExprToken;
   162    163     int nExprToken;
          164  +
          165  +  UNUSED_PARAMETER(clientData);
   163    166   
   164    167     /* Must have 3 or more arguments. */
   165    168     if( objc<3 || (objc%2)==0 ){
   166    169       Tcl_WrongNumArgs(interp, 1, objv, "DOCUMENT EXPR ?OPTION VALUE?...");
   167    170       rc = TCL_ERROR;
   168    171       goto near_match_out;
   169    172     }
................................................................................
   310    313       test_fts3_node_chunksize = iArg1;
   311    314       test_fts3_node_chunk_threshold = iArg2;
   312    315     }
   313    316   
   314    317     Tcl_SetObjResult(interp, pRet);
   315    318     Tcl_DecrRefCount(pRet);
   316    319   #endif
          320  +  UNUSED_PARAMETER(clientData);
   317    321     return TCL_OK;
   318    322   }
   319    323   
   320    324   #ifdef SQLITE_ENABLE_FTS3
   321    325   /**************************************************************************
   322    326   ** Beginning of test tokenizer code.
   323    327   **
................................................................................
   348    352   } test_tokenizer_cursor;
   349    353   
   350    354   static int testTokenizerCreate(
   351    355     int argc, const char * const *argv,
   352    356     sqlite3_tokenizer **ppTokenizer
   353    357   ){
   354    358     test_tokenizer *pNew;
          359  +  UNUSED_PARAMETER(argc);
          360  +  UNUSED_PARAMETER(argv);
   355    361   
   356    362     pNew = sqlite3_malloc(sizeof(test_tokenizer));
   357    363     if( !pNew ) return SQLITE_NOMEM;
   358    364     memset(pNew, 0, sizeof(test_tokenizer));
   359    365   
   360    366     *ppTokenizer = (sqlite3_tokenizer *)pNew;
   361    367     return SQLITE_OK;
................................................................................
   503    509       Tcl_WrongNumArgs(interp, 1, objv, "");
   504    510       return TCL_ERROR;
   505    511     }
   506    512     Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(
   507    513       (const unsigned char *)&pPtr, sizeof(sqlite3_tokenizer_module *)
   508    514     ));
   509    515   #endif
          516  +  UNUSED_PARAMETER(clientData);
   510    517     return TCL_OK;
   511    518   }
   512    519   
   513    520   /* 
   514    521   ** End of tokenizer code.
   515    522   **************************************************************************/ 
   516    523   
................................................................................
   520    527         "fts3_configure_incr_load", fts3_configure_incr_load_cmd, 0, 0
   521    528     );
   522    529     Tcl_CreateObjCommand(
   523    530         interp, "fts3_test_tokenizer", fts3_test_tokenizer_cmd, 0, 0
   524    531     );
   525    532     return TCL_OK;
   526    533   }
          534  +#endif                  /* SQLITE_ENABLE_FTS3 || SQLITE_ENABLE_FTS4 */
   527    535   #endif                  /* ifdef SQLITE_TEST */

Changes to ext/fts3/fts3_write.c.

  3735   3735       }
  3736   3736   
  3737   3737       /* Advance to the next output block */
  3738   3738       pLeaf->iBlock++;
  3739   3739       pLeaf->key.n = 0;
  3740   3740       pLeaf->block.n = 0;
  3741   3741   
  3742         -    nPrefix = 0;
  3743   3742       nSuffix = nTerm;
  3744   3743       nSpace  = 1;
  3745   3744       nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix;
  3746   3745       nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist;
  3747   3746     }
  3748   3747   
  3749   3748     blobGrowBuffer(&pLeaf->block, pLeaf->block.n + nSpace, &rc);

Changes to ext/rtree/rtree.c.

   178    178     int eCoordType;
   179    179   };
   180    180   
   181    181   /* Possible values for eCoordType: */
   182    182   #define RTREE_COORD_REAL32 0
   183    183   #define RTREE_COORD_INT32  1
   184    184   
          185  +/*
          186  +** If SQLITE_RTREE_INT_ONLY is defined, then this virtual table will
          187  +** only deal with integer coordinates.  No floating point operations
          188  +** will be done.
          189  +*/
          190  +#ifdef SQLITE_RTREE_INT_ONLY
          191  +  typedef sqlite3_int64 RtreeDValue;       /* High accuracy coordinate */
          192  +  typedef int RtreeValue;                  /* Low accuracy coordinate */
          193  +#else
          194  +  typedef double RtreeDValue;              /* High accuracy coordinate */
          195  +  typedef float RtreeValue;                /* Low accuracy coordinate */
          196  +#endif
          197  +
   185    198   /*
   186    199   ** The minimum number of cells allowed for a node is a third of the 
   187    200   ** maximum. In Gutman's notation:
   188    201   **
   189    202   **     m = M/3
   190    203   **
   191    204   ** If an R*-tree "Reinsert" operation is required, the same number of
................................................................................
   213    226     int iCell;                        /* Index of current cell in pNode */
   214    227     int iStrategy;                    /* Copy of idxNum search parameter */
   215    228     int nConstraint;                  /* Number of entries in aConstraint */
   216    229     RtreeConstraint *aConstraint;     /* Search constraints. */
   217    230   };
   218    231   
   219    232   union RtreeCoord {
   220         -  float f;
          233  +  RtreeValue f;
   221    234     int i;
   222    235   };
   223    236   
   224    237   /*
   225    238   ** The argument is an RtreeCoord. Return the value stored within the RtreeCoord
   226         -** formatted as a double. This macro assumes that local variable pRtree points
   227         -** to the Rtree structure associated with the RtreeCoord.
          239  +** formatted as a RtreeDValue (double or int64). This macro assumes that local
          240  +** variable pRtree points to the Rtree structure associated with the
          241  +** RtreeCoord.
   228    242   */
   229         -#define DCOORD(coord) (                           \
   230         -  (pRtree->eCoordType==RTREE_COORD_REAL32) ?      \
   231         -    ((double)coord.f) :                           \
   232         -    ((double)coord.i)                             \
   233         -)
          243  +#ifdef SQLITE_RTREE_INT_ONLY
          244  +# define DCOORD(coord) ((RtreeDValue)coord.i)
          245  +#else
          246  +# define DCOORD(coord) (                           \
          247  +    (pRtree->eCoordType==RTREE_COORD_REAL32) ?      \
          248  +      ((double)coord.f) :                           \
          249  +      ((double)coord.i)                             \
          250  +  )
          251  +#endif
   234    252   
   235    253   /*
   236    254   ** A search constraint.
   237    255   */
   238    256   struct RtreeConstraint {
   239    257     int iCoord;                     /* Index of constrained coordinate */
   240    258     int op;                         /* Constraining operation */
   241         -  double rValue;                  /* Constraint value. */
   242         -  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *);
          259  +  RtreeDValue rValue;             /* Constraint value. */
          260  +  int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*);
   243    261     sqlite3_rtree_geometry *pGeom;  /* Constraint callback argument for a MATCH */
   244    262   };
   245    263   
   246    264   /* Possible values for RtreeConstraint.op */
   247    265   #define RTREE_EQ    0x41
   248    266   #define RTREE_LE    0x42
   249    267   #define RTREE_LT    0x43
................................................................................
   283    301   /*
   284    302   ** An instance of this structure must be supplied as a blob argument to
   285    303   ** the right-hand-side of an SQL MATCH operator used to constrain an
   286    304   ** r-tree query.
   287    305   */
   288    306   struct RtreeMatchArg {
   289    307     u32 magic;                      /* Always RTREE_GEOMETRY_MAGIC */
   290         -  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *);
          308  +  int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue*, int *);
   291    309     void *pContext;
   292    310     int nParam;
   293         -  double aParam[1];
          311  +  RtreeDValue aParam[1];
   294    312   };
   295    313   
   296    314   /*
   297    315   ** When a geometry callback is created (see sqlite3_rtree_geometry_callback),
   298    316   ** a single instance of the following structure is allocated. It is used
   299    317   ** as the context for the user-function created by by s_r_g_c(). The object
   300    318   ** is eventually deleted by the destructor mechanism provided by
   301    319   ** sqlite3_create_function_v2() (which is called by s_r_g_c() to create
   302    320   ** the geometry callback function).
   303    321   */
   304    322   struct RtreeGeomCallback {
   305         -  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *);
          323  +  int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*);
   306    324     void *pContext;
   307    325   };
   308    326   
   309    327   #ifndef MAX
   310    328   # define MAX(x,y) ((x) < (y) ? (y) : (x))
   311    329   #endif
   312    330   #ifndef MIN
................................................................................
   864    882   static int testRtreeGeom(
   865    883     Rtree *pRtree,                  /* R-Tree object */
   866    884     RtreeConstraint *pConstraint,   /* MATCH constraint to test */
   867    885     RtreeCell *pCell,               /* Cell to test */
   868    886     int *pbRes                      /* OUT: Test result */
   869    887   ){
   870    888     int i;
   871         -  double aCoord[RTREE_MAX_DIMENSIONS*2];
          889  +  RtreeDValue aCoord[RTREE_MAX_DIMENSIONS*2];
   872    890     int nCoord = pRtree->nDim*2;
   873    891   
   874    892     assert( pConstraint->op==RTREE_MATCH );
   875    893     assert( pConstraint->pGeom );
   876    894   
   877    895     for(i=0; i<nCoord; i++){
   878    896       aCoord[i] = DCOORD(pCell->aCoord[i]);
................................................................................
   894    912     int ii;
   895    913     int bRes = 0;
   896    914     int rc = SQLITE_OK;
   897    915   
   898    916     nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
   899    917     for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){
   900    918       RtreeConstraint *p = &pCursor->aConstraint[ii];
   901         -    double cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]);
   902         -    double cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]);
          919  +    RtreeDValue cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]);
          920  +    RtreeDValue cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]);
   903    921   
   904    922       assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE 
   905    923           || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH
   906    924       );
   907    925   
   908    926       switch( p->op ){
   909    927         case RTREE_LE: case RTREE_LT: 
................................................................................
   947    965     RtreeCell cell;
   948    966     int ii;
   949    967     *pbEof = 0;
   950    968   
   951    969     nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
   952    970     for(ii=0; ii<pCursor->nConstraint; ii++){
   953    971       RtreeConstraint *p = &pCursor->aConstraint[ii];
   954         -    double coord = DCOORD(cell.aCoord[p->iCoord]);
          972  +    RtreeDValue coord = DCOORD(cell.aCoord[p->iCoord]);
   955    973       int res;
   956    974       assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE 
   957    975           || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH
   958    976       );
   959    977       switch( p->op ){
   960    978         case RTREE_LE: res = (coord<=p->rValue); break;
   961    979         case RTREE_LT: res = (coord<p->rValue);  break;
................................................................................
  1145   1163   
  1146   1164     if( i==0 ){
  1147   1165       i64 iRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell);
  1148   1166       sqlite3_result_int64(ctx, iRowid);
  1149   1167     }else{
  1150   1168       RtreeCoord c;
  1151   1169       nodeGetCoord(pRtree, pCsr->pNode, pCsr->iCell, i-1, &c);
         1170  +#ifndef SQLITE_RTREE_INT_ONLY
  1152   1171       if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
  1153   1172         sqlite3_result_double(ctx, c.f);
  1154         -    }else{
         1173  +    }else
         1174  +#endif
         1175  +    {
  1155   1176         assert( pRtree->eCoordType==RTREE_COORD_INT32 );
  1156   1177         sqlite3_result_int(ctx, c.i);
  1157   1178       }
  1158   1179     }
  1159   1180   
  1160   1181     return SQLITE_OK;
  1161   1182   }
................................................................................
  1194   1215   
  1195   1216     /* Check that value is actually a blob. */
  1196   1217     if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR;
  1197   1218   
  1198   1219     /* Check that the blob is roughly the right size. */
  1199   1220     nBlob = sqlite3_value_bytes(pValue);
  1200   1221     if( nBlob<(int)sizeof(RtreeMatchArg) 
  1201         -   || ((nBlob-sizeof(RtreeMatchArg))%sizeof(double))!=0
         1222  +   || ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0
  1202   1223     ){
  1203   1224       return SQLITE_ERROR;
  1204   1225     }
  1205   1226   
  1206   1227     pGeom = (sqlite3_rtree_geometry *)sqlite3_malloc(
  1207   1228         sizeof(sqlite3_rtree_geometry) + nBlob
  1208   1229     );
  1209   1230     if( !pGeom ) return SQLITE_NOMEM;
  1210   1231     memset(pGeom, 0, sizeof(sqlite3_rtree_geometry));
  1211   1232     p = (RtreeMatchArg *)&pGeom[1];
  1212   1233   
  1213   1234     memcpy(p, sqlite3_value_blob(pValue), nBlob);
  1214   1235     if( p->magic!=RTREE_GEOMETRY_MAGIC 
  1215         -   || nBlob!=(int)(sizeof(RtreeMatchArg) + (p->nParam-1)*sizeof(double))
         1236  +   || nBlob!=(int)(sizeof(RtreeMatchArg) + (p->nParam-1)*sizeof(RtreeDValue))
  1216   1237     ){
  1217   1238       sqlite3_free(pGeom);
  1218   1239       return SQLITE_ERROR;
  1219   1240     }
  1220   1241   
  1221   1242     pGeom->pContext = p->pContext;
  1222   1243     pGeom->nParam = p->nParam;
................................................................................
  1280   1301               ** an sqlite3_rtree_geometry_callback() SQL user function.
  1281   1302               */
  1282   1303               rc = deserializeGeometry(argv[ii], p);
  1283   1304               if( rc!=SQLITE_OK ){
  1284   1305                 break;
  1285   1306               }
  1286   1307             }else{
         1308  +#ifdef SQLITE_RTREE_INT_ONLY
         1309  +            p->rValue = sqlite3_value_int64(argv[ii]);
         1310  +#else
  1287   1311               p->rValue = sqlite3_value_double(argv[ii]);
         1312  +#endif
  1288   1313             }
  1289   1314           }
  1290   1315         }
  1291   1316       }
  1292   1317     
  1293   1318       if( rc==SQLITE_OK ){
  1294   1319         pCsr->pNode = 0;
................................................................................
  1414   1439     pIdxInfo->estimatedCost = (2000000.0 / (double)(iIdx + 1));
  1415   1440     return rc;
  1416   1441   }
  1417   1442   
  1418   1443   /*
  1419   1444   ** Return the N-dimensional volumn of the cell stored in *p.
  1420   1445   */
  1421         -static float cellArea(Rtree *pRtree, RtreeCell *p){
  1422         -  float area = 1.0;
         1446  +static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){
         1447  +  RtreeDValue area = (RtreeDValue)1;
  1423   1448     int ii;
  1424   1449     for(ii=0; ii<(pRtree->nDim*2); ii+=2){
  1425         -    area = (float)(area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])));
         1450  +    area = (area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])));
  1426   1451     }
  1427   1452     return area;
  1428   1453   }
  1429   1454   
  1430   1455   /*
  1431   1456   ** Return the margin length of cell p. The margin length is the sum
  1432   1457   ** of the objects size in each dimension.
  1433   1458   */
  1434         -static float cellMargin(Rtree *pRtree, RtreeCell *p){
  1435         -  float margin = 0.0;
         1459  +static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){
         1460  +  RtreeDValue margin = (RtreeDValue)0;
  1436   1461     int ii;
  1437   1462     for(ii=0; ii<(pRtree->nDim*2); ii+=2){
  1438         -    margin += (float)(DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
         1463  +    margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
  1439   1464     }
  1440   1465     return margin;
  1441   1466   }
  1442   1467   
  1443   1468   /*
  1444   1469   ** Store the union of cells p1 and p2 in p1.
  1445   1470   */
................................................................................
  1476   1501     }
  1477   1502     return 1;
  1478   1503   }
  1479   1504   
  1480   1505   /*
  1481   1506   ** Return the amount cell p would grow by if it were unioned with pCell.
  1482   1507   */
  1483         -static float cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){
  1484         -  float area;
         1508  +static RtreeDValue cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){
         1509  +  RtreeDValue area;
  1485   1510     RtreeCell cell;
  1486   1511     memcpy(&cell, p, sizeof(RtreeCell));
  1487   1512     area = cellArea(pRtree, &cell);
  1488   1513     cellUnion(pRtree, &cell, pCell);
  1489   1514     return (cellArea(pRtree, &cell)-area);
  1490   1515   }
  1491   1516   
  1492   1517   #if VARIANT_RSTARTREE_CHOOSESUBTREE || VARIANT_RSTARTREE_SPLIT
  1493         -static float cellOverlap(
         1518  +static RtreeDValue cellOverlap(
  1494   1519     Rtree *pRtree, 
  1495   1520     RtreeCell *p, 
  1496   1521     RtreeCell *aCell, 
  1497   1522     int nCell, 
  1498   1523     int iExclude
  1499   1524   ){
  1500   1525     int ii;
  1501         -  float overlap = 0.0;
         1526  +  RtreeDValue overlap = 0.0;
  1502   1527     for(ii=0; ii<nCell; ii++){
  1503   1528   #if VARIANT_RSTARTREE_CHOOSESUBTREE
  1504   1529       if( ii!=iExclude )
  1505   1530   #else
  1506   1531       assert( iExclude==-1 );
  1507   1532       UNUSED_PARAMETER(iExclude);
  1508   1533   #endif
  1509   1534       {
  1510   1535         int jj;
  1511         -      float o = 1.0;
         1536  +      RtreeDValue o = (RtreeDValue)1;
  1512   1537         for(jj=0; jj<(pRtree->nDim*2); jj+=2){
  1513         -        double x1;
  1514         -        double x2;
         1538  +        RtreeDValue x1, x2;
  1515   1539   
  1516   1540           x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj]));
  1517   1541           x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1]));
  1518   1542   
  1519   1543           if( x2<x1 ){
  1520   1544             o = 0.0;
  1521   1545             break;
  1522   1546           }else{
  1523         -          o = o * (float)(x2-x1);
         1547  +          o = o * (x2-x1);
  1524   1548           }
  1525   1549         }
  1526   1550         overlap += o;
  1527   1551       }
  1528   1552     }
  1529   1553     return overlap;
  1530   1554   }
  1531   1555   #endif
  1532   1556   
  1533   1557   #if VARIANT_RSTARTREE_CHOOSESUBTREE
  1534         -static float cellOverlapEnlargement(
         1558  +static RtreeDValue cellOverlapEnlargement(
  1535   1559     Rtree *pRtree, 
  1536   1560     RtreeCell *p, 
  1537   1561     RtreeCell *pInsert, 
  1538   1562     RtreeCell *aCell, 
  1539   1563     int nCell, 
  1540   1564     int iExclude
  1541   1565   ){
  1542         -  double before;
  1543         -  double after;
         1566  +  RtreeDValue before, after;
  1544   1567     before = cellOverlap(pRtree, p, aCell, nCell, iExclude);
  1545   1568     cellUnion(pRtree, p, pInsert);
  1546   1569     after = cellOverlap(pRtree, p, aCell, nCell, iExclude);
  1547         -  return (float)(after-before);
         1570  +  return (after-before);
  1548   1571   }
  1549   1572   #endif
  1550   1573   
  1551   1574   
  1552   1575   /*
  1553   1576   ** This function implements the ChooseLeaf algorithm from Gutman[84].
  1554   1577   ** ChooseSubTree in r*tree terminology.
................................................................................
  1564   1587     RtreeNode *pNode;
  1565   1588     rc = nodeAcquire(pRtree, 1, 0, &pNode);
  1566   1589   
  1567   1590     for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){
  1568   1591       int iCell;
  1569   1592       sqlite3_int64 iBest = 0;
  1570   1593   
  1571         -    float fMinGrowth = 0.0;
  1572         -    float fMinArea = 0.0;
         1594  +    RtreeDValue fMinGrowth = 0.0;
         1595  +    RtreeDValue fMinArea = 0.0;
  1573   1596   #if VARIANT_RSTARTREE_CHOOSESUBTREE
  1574         -    float fMinOverlap = 0.0;
  1575         -    float overlap;
         1597  +    RtreeDValue fMinOverlap = 0.0;
         1598  +    RtreeDValue overlap;
  1576   1599   #endif
  1577   1600   
  1578   1601       int nCell = NCELL(pNode);
  1579   1602       RtreeCell cell;
  1580   1603       RtreeNode *pChild;
  1581   1604   
  1582   1605       RtreeCell *aCell = 0;
................................................................................
  1599   1622   
  1600   1623       /* Select the child node which will be enlarged the least if pCell
  1601   1624       ** is inserted into it. Resolve ties by choosing the entry with
  1602   1625       ** the smallest area.
  1603   1626       */
  1604   1627       for(iCell=0; iCell<nCell; iCell++){
  1605   1628         int bBest = 0;
  1606         -      float growth;
  1607         -      float area;
         1629  +      RtreeDValue growth;
         1630  +      RtreeDValue area;
  1608   1631         nodeGetCell(pRtree, pNode, iCell, &cell);
  1609   1632         growth = cellGrowth(pRtree, &cell, pCell);
  1610   1633         area = cellArea(pRtree, &cell);
  1611   1634   
  1612   1635   #if VARIANT_RSTARTREE_CHOOSESUBTREE
  1613   1636         if( ii==(pRtree->iDepth-1) ){
  1614   1637           overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell);
................................................................................
  1727   1750     int nCell, 
  1728   1751     int *piLeftSeed, 
  1729   1752     int *piRightSeed
  1730   1753   ){
  1731   1754     int i;
  1732   1755     int iLeftSeed = 0;
  1733   1756     int iRightSeed = 1;
  1734         -  float maxNormalInnerWidth = 0.0;
         1757  +  RtreeDValue maxNormalInnerWidth = (RtreeDValue)0;
  1735   1758   
  1736   1759     /* Pick two "seed" cells from the array of cells. The algorithm used
  1737   1760     ** here is the LinearPickSeeds algorithm from Gutman[1984]. The 
  1738   1761     ** indices of the two seed cells in the array are stored in local
  1739   1762     ** variables iLeftSeek and iRightSeed.
  1740   1763     */
  1741   1764     for(i=0; i<pRtree->nDim; i++){
  1742         -    float x1 = DCOORD(aCell[0].aCoord[i*2]);
  1743         -    float x2 = DCOORD(aCell[0].aCoord[i*2+1]);
  1744         -    float x3 = x1;
  1745         -    float x4 = x2;
         1765  +    RtreeDValue x1 = DCOORD(aCell[0].aCoord[i*2]);
         1766  +    RtreeDValue x2 = DCOORD(aCell[0].aCoord[i*2+1]);
         1767  +    RtreeDValue x3 = x1;
         1768  +    RtreeDValue x4 = x2;
  1746   1769       int jj;
  1747   1770   
  1748   1771       int iCellLeft = 0;
  1749   1772       int iCellRight = 0;
  1750   1773   
  1751   1774       for(jj=1; jj<nCell; jj++){
  1752         -      float left = DCOORD(aCell[jj].aCoord[i*2]);
  1753         -      float right = DCOORD(aCell[jj].aCoord[i*2+1]);
         1775  +      RtreeDValue left = DCOORD(aCell[jj].aCoord[i*2]);
         1776  +      RtreeDValue right = DCOORD(aCell[jj].aCoord[i*2+1]);
  1754   1777   
  1755   1778         if( left<x1 ) x1 = left;
  1756   1779         if( right>x4 ) x4 = right;
  1757   1780         if( left>x3 ){
  1758   1781           x3 = left;
  1759   1782           iCellRight = jj;
  1760   1783         }
................................................................................
  1761   1784         if( right<x2 ){
  1762   1785           x2 = right;
  1763   1786           iCellLeft = jj;
  1764   1787         }
  1765   1788       }
  1766   1789   
  1767   1790       if( x4!=x1 ){
  1768         -      float normalwidth = (x3 - x2) / (x4 - x1);
         1791  +      RtreeDValue normalwidth = (x3 - x2) / (x4 - x1);
  1769   1792         if( normalwidth>maxNormalInnerWidth ){
  1770   1793           iLeftSeed = iCellLeft;
  1771   1794           iRightSeed = iCellRight;
  1772   1795         }
  1773   1796       }
  1774   1797     }
  1775   1798   
................................................................................
  1790   1813     RtreeCell *pLeftBox, 
  1791   1814     RtreeCell *pRightBox,
  1792   1815     int *aiUsed
  1793   1816   ){
  1794   1817     #define FABS(a) ((a)<0.0?-1.0*(a):(a))
  1795   1818   
  1796   1819     int iSelect = -1;
  1797         -  float fDiff;
         1820  +  RtreeDValue fDiff;
  1798   1821     int ii;
  1799   1822     for(ii=0; ii<nCell; ii++){
  1800   1823       if( aiUsed[ii]==0 ){
  1801         -      float left = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
  1802         -      float right = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
  1803         -      float diff = FABS(right-left);
         1824  +      RtreeDValue left = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
         1825  +      RtreeDValue right = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
         1826  +      RtreeDValue diff = FABS(right-left);
  1804   1827         if( iSelect<0 || diff>fDiff ){
  1805   1828           fDiff = diff;
  1806   1829           iSelect = ii;
  1807   1830         }
  1808   1831       }
  1809   1832     }
  1810   1833     aiUsed[iSelect] = 1;
................................................................................
  1823   1846     int *piRightSeed
  1824   1847   ){
  1825   1848     int ii;
  1826   1849     int jj;
  1827   1850   
  1828   1851     int iLeftSeed = 0;
  1829   1852     int iRightSeed = 1;
  1830         -  float fWaste = 0.0;
         1853  +  RtreeDValue fWaste = 0.0;
  1831   1854   
  1832   1855     for(ii=0; ii<nCell; ii++){
  1833   1856       for(jj=ii+1; jj<nCell; jj++){
  1834         -      float right = cellArea(pRtree, &aCell[jj]);
  1835         -      float growth = cellGrowth(pRtree, &aCell[ii], &aCell[jj]);
  1836         -      float waste = growth - right;
         1857  +      RtreeDValue right = cellArea(pRtree, &aCell[jj]);
         1858  +      RtreeDValue growth = cellGrowth(pRtree, &aCell[ii], &aCell[jj]);
         1859  +      RtreeDValue waste = growth - right;
  1837   1860   
  1838   1861         if( waste>fWaste ){
  1839   1862           iLeftSeed = ii;
  1840   1863           iRightSeed = jj;
  1841   1864           fWaste = waste;
  1842   1865         }
  1843   1866       }
................................................................................
  1864   1887   **
  1865   1888   ** The aSpare array is used as temporary working space by the
  1866   1889   ** sorting algorithm.
  1867   1890   */
  1868   1891   static void SortByDistance(
  1869   1892     int *aIdx, 
  1870   1893     int nIdx, 
  1871         -  float *aDistance, 
         1894  +  RtreeDValue *aDistance, 
  1872   1895     int *aSpare
  1873   1896   ){
  1874   1897     if( nIdx>1 ){
  1875   1898       int iLeft = 0;
  1876   1899       int iRight = 0;
  1877   1900   
  1878   1901       int nLeft = nIdx/2;
................................................................................
  1890   1913         if( iLeft==nLeft ){
  1891   1914           aIdx[iLeft+iRight] = aRight[iRight];
  1892   1915           iRight++;
  1893   1916         }else if( iRight==nRight ){
  1894   1917           aIdx[iLeft+iRight] = aLeft[iLeft];
  1895   1918           iLeft++;
  1896   1919         }else{
  1897         -        float fLeft = aDistance[aLeft[iLeft]];
  1898         -        float fRight = aDistance[aRight[iRight]];
         1920  +        RtreeDValue fLeft = aDistance[aLeft[iLeft]];
         1921  +        RtreeDValue fRight = aDistance[aRight[iRight]];
  1899   1922           if( fLeft<fRight ){
  1900   1923             aIdx[iLeft+iRight] = aLeft[iLeft];
  1901   1924             iLeft++;
  1902   1925           }else{
  1903   1926             aIdx[iLeft+iRight] = aRight[iRight];
  1904   1927             iRight++;
  1905   1928           }
................................................................................
  1907   1930       }
  1908   1931   
  1909   1932   #if 0
  1910   1933       /* Check that the sort worked */
  1911   1934       {
  1912   1935         int jj;
  1913   1936         for(jj=1; jj<nIdx; jj++){
  1914         -        float left = aDistance[aIdx[jj-1]];
  1915         -        float right = aDistance[aIdx[jj]];
         1937  +        RtreeDValue left = aDistance[aIdx[jj-1]];
         1938  +        RtreeDValue right = aDistance[aIdx[jj]];
  1916   1939           assert( left<=right );
  1917   1940         }
  1918   1941       }
  1919   1942   #endif
  1920   1943     }
  1921   1944   }
  1922   1945   
................................................................................
  1951   1974   
  1952   1975       SortByDimension(pRtree, aLeft, nLeft, iDim, aCell, aSpare);
  1953   1976       SortByDimension(pRtree, aRight, nRight, iDim, aCell, aSpare);
  1954   1977   
  1955   1978       memcpy(aSpare, aLeft, sizeof(int)*nLeft);
  1956   1979       aLeft = aSpare;
  1957   1980       while( iLeft<nLeft || iRight<nRight ){
  1958         -      double xleft1 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2]);
  1959         -      double xleft2 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2+1]);
  1960         -      double xright1 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2]);
  1961         -      double xright2 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2+1]);
         1981  +      RtreeDValue xleft1 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2]);
         1982  +      RtreeDValue xleft2 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2+1]);
         1983  +      RtreeDValue xright1 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2]);
         1984  +      RtreeDValue xright2 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2+1]);
  1962   1985         if( (iLeft!=nLeft) && ((iRight==nRight)
  1963   1986          || (xleft1<xright1)
  1964   1987          || (xleft1==xright1 && xleft2<xright2)
  1965   1988         )){
  1966   1989           aIdx[iLeft+iRight] = aLeft[iLeft];
  1967   1990           iLeft++;
  1968   1991         }else{
................................................................................
  1972   1995       }
  1973   1996   
  1974   1997   #if 0
  1975   1998       /* Check that the sort worked */
  1976   1999       {
  1977   2000         int jj;
  1978   2001         for(jj=1; jj<nIdx; jj++){
  1979         -        float xleft1 = aCell[aIdx[jj-1]].aCoord[iDim*2];
  1980         -        float xleft2 = aCell[aIdx[jj-1]].aCoord[iDim*2+1];
  1981         -        float xright1 = aCell[aIdx[jj]].aCoord[iDim*2];
  1982         -        float xright2 = aCell[aIdx[jj]].aCoord[iDim*2+1];
         2002  +        RtreeDValue xleft1 = aCell[aIdx[jj-1]].aCoord[iDim*2];
         2003  +        RtreeDValue xleft2 = aCell[aIdx[jj-1]].aCoord[iDim*2+1];
         2004  +        RtreeDValue xright1 = aCell[aIdx[jj]].aCoord[iDim*2];
         2005  +        RtreeDValue xright2 = aCell[aIdx[jj]].aCoord[iDim*2+1];
  1983   2006           assert( xleft1<=xright1 && (xleft1<xright1 || xleft2<=xright2) );
  1984   2007         }
  1985   2008       }
  1986   2009   #endif
  1987   2010     }
  1988   2011   }
  1989   2012   
................................................................................
  2002   2025   ){
  2003   2026     int **aaSorted;
  2004   2027     int *aSpare;
  2005   2028     int ii;
  2006   2029   
  2007   2030     int iBestDim = 0;
  2008   2031     int iBestSplit = 0;
  2009         -  float fBestMargin = 0.0;
         2032  +  RtreeDValue fBestMargin = 0.0;
  2010   2033   
  2011   2034     int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int));
  2012   2035   
  2013   2036     aaSorted = (int **)sqlite3_malloc(nByte);
  2014   2037     if( !aaSorted ){
  2015   2038       return SQLITE_NOMEM;
  2016   2039     }
................................................................................
  2023   2046       for(jj=0; jj<nCell; jj++){
  2024   2047         aaSorted[ii][jj] = jj;
  2025   2048       }
  2026   2049       SortByDimension(pRtree, aaSorted[ii], nCell, ii, aCell, aSpare);
  2027   2050     }
  2028   2051   
  2029   2052     for(ii=0; ii<pRtree->nDim; ii++){
  2030         -    float margin = 0.0;
  2031         -    float fBestOverlap = 0.0;
  2032         -    float fBestArea = 0.0;
         2053  +    RtreeDValue margin = 0.0;
         2054  +    RtreeDValue fBestOverlap = 0.0;
         2055  +    RtreeDValue fBestArea = 0.0;
  2033   2056       int iBestLeft = 0;
  2034   2057       int nLeft;
  2035   2058   
  2036   2059       for(
  2037   2060         nLeft=RTREE_MINCELLS(pRtree); 
  2038   2061         nLeft<=(nCell-RTREE_MINCELLS(pRtree)); 
  2039   2062         nLeft++
  2040   2063       ){
  2041   2064         RtreeCell left;
  2042   2065         RtreeCell right;
  2043   2066         int kk;
  2044         -      float overlap;
  2045         -      float area;
         2067  +      RtreeDValue overlap;
         2068  +      RtreeDValue area;
  2046   2069   
  2047   2070         memcpy(&left, &aCell[aaSorted[ii][0]], sizeof(RtreeCell));
  2048   2071         memcpy(&right, &aCell[aaSorted[ii][nCell-1]], sizeof(RtreeCell));
  2049   2072         for(kk=1; kk<(nCell-1); kk++){
  2050   2073           if( kk<nLeft ){
  2051   2074             cellUnion(pRtree, &left, &aCell[aaSorted[ii][kk]]);
  2052   2075           }else{
................................................................................
  2121   2144     nodeInsertCell(pRtree, pRight, &aCell[iRightSeed]);
  2122   2145     aiUsed[iLeftSeed] = 1;
  2123   2146     aiUsed[iRightSeed] = 1;
  2124   2147   
  2125   2148     for(i=nCell-2; i>0; i--){
  2126   2149       RtreeCell *pNext;
  2127   2150       pNext = PickNext(pRtree, aCell, nCell, pBboxLeft, pBboxRight, aiUsed);
  2128         -    float diff =  
         2151  +    RtreeDValue diff =  
  2129   2152         cellGrowth(pRtree, pBboxLeft, pNext) - 
  2130   2153         cellGrowth(pRtree, pBboxRight, pNext)
  2131   2154       ;
  2132   2155       if( (RTREE_MINCELLS(pRtree)-NCELL(pRight)==i)
  2133   2156        || (diff>0.0 && (RTREE_MINCELLS(pRtree)-NCELL(pLeft)!=i))
  2134   2157       ){
  2135   2158         nodeInsertCell(pRtree, pRight, pNext);
................................................................................
  2454   2477     RtreeNode *pNode, 
  2455   2478     RtreeCell *pCell, 
  2456   2479     int iHeight
  2457   2480   ){
  2458   2481     int *aOrder;
  2459   2482     int *aSpare;
  2460   2483     RtreeCell *aCell;
  2461         -  float *aDistance;
         2484  +  RtreeDValue *aDistance;
  2462   2485     int nCell;
  2463         -  float aCenterCoord[RTREE_MAX_DIMENSIONS];
         2486  +  RtreeDValue aCenterCoord[RTREE_MAX_DIMENSIONS];
  2464   2487     int iDim;
  2465   2488     int ii;
  2466   2489     int rc = SQLITE_OK;
         2490  +  int n;
  2467   2491   
  2468         -  memset(aCenterCoord, 0, sizeof(float)*RTREE_MAX_DIMENSIONS);
         2492  +  memset(aCenterCoord, 0, sizeof(RtreeDValue)*RTREE_MAX_DIMENSIONS);
  2469   2493   
  2470   2494     nCell = NCELL(pNode)+1;
         2495  +  n = (nCell+1)&(~1);
  2471   2496   
  2472   2497     /* Allocate the buffers used by this operation. The allocation is
  2473   2498     ** relinquished before this function returns.
  2474   2499     */
  2475         -  aCell = (RtreeCell *)sqlite3_malloc(nCell * (
  2476         -    sizeof(RtreeCell) +         /* aCell array */
  2477         -    sizeof(int)       +         /* aOrder array */
  2478         -    sizeof(int)       +         /* aSpare array */
  2479         -    sizeof(float)               /* aDistance array */
         2500  +  aCell = (RtreeCell *)sqlite3_malloc(n * (
         2501  +    sizeof(RtreeCell)     +         /* aCell array */
         2502  +    sizeof(int)           +         /* aOrder array */
         2503  +    sizeof(int)           +         /* aSpare array */
         2504  +    sizeof(RtreeDValue)             /* aDistance array */
  2480   2505     ));
  2481   2506     if( !aCell ){
  2482   2507       return SQLITE_NOMEM;
  2483   2508     }
  2484         -  aOrder    = (int *)&aCell[nCell];
  2485         -  aSpare    = (int *)&aOrder[nCell];
  2486         -  aDistance = (float *)&aSpare[nCell];
         2509  +  aOrder    = (int *)&aCell[n];
         2510  +  aSpare    = (int *)&aOrder[n];
         2511  +  aDistance = (RtreeDValue *)&aSpare[n];
  2487   2512   
  2488   2513     for(ii=0; ii<nCell; ii++){
  2489   2514       if( ii==(nCell-1) ){
  2490   2515         memcpy(&aCell[ii], pCell, sizeof(RtreeCell));
  2491   2516       }else{
  2492   2517         nodeGetCell(pRtree, pNode, ii, &aCell[ii]);
  2493   2518       }
  2494   2519       aOrder[ii] = ii;
  2495   2520       for(iDim=0; iDim<pRtree->nDim; iDim++){
  2496         -      aCenterCoord[iDim] += (float)DCOORD(aCell[ii].aCoord[iDim*2]);
  2497         -      aCenterCoord[iDim] += (float)DCOORD(aCell[ii].aCoord[iDim*2+1]);
         2521  +      aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]);
         2522  +      aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]);
  2498   2523       }
  2499   2524     }
  2500   2525     for(iDim=0; iDim<pRtree->nDim; iDim++){
  2501         -    aCenterCoord[iDim] = (float)(aCenterCoord[iDim]/((float)nCell*2.0));
         2526  +    aCenterCoord[iDim] = (aCenterCoord[iDim]/(nCell*(RtreeDValue)2));
  2502   2527     }
  2503   2528   
  2504   2529     for(ii=0; ii<nCell; ii++){
  2505   2530       aDistance[ii] = 0.0;
  2506   2531       for(iDim=0; iDim<pRtree->nDim; iDim++){
  2507         -      float coord = (float)(DCOORD(aCell[ii].aCoord[iDim*2+1]) - 
  2508         -          DCOORD(aCell[ii].aCoord[iDim*2]));
         2532  +      RtreeDValue coord = (DCOORD(aCell[ii].aCoord[iDim*2+1]) - 
         2533  +                               DCOORD(aCell[ii].aCoord[iDim*2]));
  2509   2534         aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]);
  2510   2535       }
  2511   2536     }
  2512   2537   
  2513   2538     SortByDistance(aOrder, nCell, aDistance, aSpare);
  2514   2539     nodeZero(pRtree, pNode);
  2515   2540   
................................................................................
  2743   2768     ** conflict-handling mode specified by the user.
  2744   2769     */
  2745   2770     if( nData>1 ){
  2746   2771       int ii;
  2747   2772   
  2748   2773       /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
  2749   2774       assert( nData==(pRtree->nDim*2 + 3) );
         2775  +#ifndef SQLITE_RTREE_INT_ONLY
  2750   2776       if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
  2751   2777         for(ii=0; ii<(pRtree->nDim*2); ii+=2){
  2752         -        cell.aCoord[ii].f = (float)sqlite3_value_double(azData[ii+3]);
  2753         -        cell.aCoord[ii+1].f = (float)sqlite3_value_double(azData[ii+4]);
         2778  +        cell.aCoord[ii].f = (RtreeValue)sqlite3_value_double(azData[ii+3]);
         2779  +        cell.aCoord[ii+1].f = (RtreeValue)sqlite3_value_double(azData[ii+4]);
  2754   2780           if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
  2755   2781             rc = SQLITE_CONSTRAINT;
  2756   2782             goto constraint;
  2757   2783           }
  2758   2784         }
  2759         -    }else{
         2785  +    }else
         2786  +#endif
         2787  +    {
  2760   2788         for(ii=0; ii<(pRtree->nDim*2); ii+=2){
  2761   2789           cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
  2762   2790           cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
  2763   2791           if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
  2764   2792             rc = SQLITE_CONSTRAINT;
  2765   2793             goto constraint;
  2766   2794           }
................................................................................
  3150   3178       RtreeCell cell;
  3151   3179       int jj;
  3152   3180   
  3153   3181       nodeGetCell(&tree, &node, ii, &cell);
  3154   3182       sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid);
  3155   3183       nCell = (int)strlen(zCell);
  3156   3184       for(jj=0; jj<tree.nDim*2; jj++){
  3157         -      sqlite3_snprintf(512-nCell,&zCell[nCell]," %f",(double)cell.aCoord[jj].f);
         3185  +#ifndef SQLITE_RTREE_INT_ONLY
         3186  +      sqlite3_snprintf(512-nCell,&zCell[nCell], " %f",
         3187  +                       (double)cell.aCoord[jj].f);
         3188  +#else
         3189  +      sqlite3_snprintf(512-nCell,&zCell[nCell], " %d",
         3190  +                       cell.aCoord[jj].i);
         3191  +#endif
  3158   3192         nCell = (int)strlen(zCell);
  3159   3193       }
  3160   3194   
  3161   3195       if( zText ){
  3162   3196         char *zTextNew = sqlite3_mprintf("%s {%s}", zText, zCell);
  3163   3197         sqlite3_free(zText);
  3164   3198         zText = zTextNew;
................................................................................
  3192   3226     int rc;
  3193   3227   
  3194   3228     rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0);
  3195   3229     if( rc==SQLITE_OK ){
  3196   3230       rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0);
  3197   3231     }
  3198   3232     if( rc==SQLITE_OK ){
         3233  +#ifdef SQLITE_RTREE_INT_ONLY
         3234  +    void *c = (void *)RTREE_COORD_INT32;
         3235  +#else
  3199   3236       void *c = (void *)RTREE_COORD_REAL32;
         3237  +#endif
  3200   3238       rc = sqlite3_create_module_v2(db, "rtree", &rtreeModule, c, 0);
  3201   3239     }
  3202   3240     if( rc==SQLITE_OK ){
  3203   3241       void *c = (void *)RTREE_COORD_INT32;
  3204   3242       rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0);
  3205   3243     }
  3206   3244   
................................................................................
  3226   3264   ** table MATCH operators.
  3227   3265   */
  3228   3266   static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
  3229   3267     RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx);
  3230   3268     RtreeMatchArg *pBlob;
  3231   3269     int nBlob;
  3232   3270   
  3233         -  nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(double);
         3271  +  nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue);
  3234   3272     pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob);
  3235   3273     if( !pBlob ){
  3236   3274       sqlite3_result_error_nomem(ctx);
  3237   3275     }else{
  3238   3276       int i;
  3239   3277       pBlob->magic = RTREE_GEOMETRY_MAGIC;
  3240   3278       pBlob->xGeom = pGeomCtx->xGeom;
  3241   3279       pBlob->pContext = pGeomCtx->pContext;
  3242   3280       pBlob->nParam = nArg;
  3243   3281       for(i=0; i<nArg; i++){
         3282  +#ifdef SQLITE_RTREE_INT_ONLY
         3283  +      pBlob->aParam[i] = sqlite3_value_int64(aArg[i]);
         3284  +#else
  3244   3285         pBlob->aParam[i] = sqlite3_value_double(aArg[i]);
         3286  +#endif
  3245   3287       }
  3246   3288       sqlite3_result_blob(ctx, pBlob, nBlob, doSqlite3Free);
  3247   3289     }
  3248   3290   }
  3249   3291   
  3250   3292   /*
  3251   3293   ** Register a new geometry function for use with the r-tree MATCH operator.
  3252   3294   */
  3253   3295   int sqlite3_rtree_geometry_callback(
  3254   3296     sqlite3 *db,
  3255   3297     const char *zGeom,
  3256         -  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *),
         3298  +  int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue *, int *),
  3257   3299     void *pContext
  3258   3300   ){
  3259   3301     RtreeGeomCallback *pGeomCtx;      /* Context object for new user-function */
  3260   3302   
  3261   3303     /* Allocate and populate the context object. */
  3262   3304     pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback));
  3263   3305     if( !pGeomCtx ) return SQLITE_NOMEM;

Changes to ext/rtree/rtree1.test.

    99     99       catchsql " 
   100    100         CREATE VIRTUAL TABLE t1 USING rtree($columns);
   101    101       "
   102    102     } $X
   103    103   
   104    104     catchsql { DROP TABLE t1 }
   105    105   }
          106  +
          107  +# Like execsql except display output as integer where that can be
          108  +# done without loss of information.
          109  +#
          110  +proc execsql_intout {sql} {
          111  +  set out {}
          112  +  foreach term [execsql $sql] {
          113  +    regsub {\.0$} $term {} term
          114  +    lappend out $term
          115  +  }
          116  +  return $out
          117  +}
   106    118   
   107    119   # Test that it is possible to open an existing database that contains
   108    120   # r-tree tables.
   109    121   #
   110    122   do_test rtree-1.4.1 {
   111    123     execsql {
   112    124       CREATE VIRTUAL TABLE t1 USING rtree(ii, x1, x2);
................................................................................
   113    125       INSERT INTO t1 VALUES(1, 5.0, 10.0);
   114    126       INSERT INTO t1 VALUES(2, 15.0, 20.0);
   115    127     }
   116    128   } {}
   117    129   do_test rtree-1.4.2 {
   118    130     db close
   119    131     sqlite3 db test.db
   120         -  execsql { SELECT * FROM t1 ORDER BY ii }
   121         -} {1 5.0 10.0 2 15.0 20.0}
          132  +  execsql_intout { SELECT * FROM t1 ORDER BY ii }
          133  +} {1 5 10 2 15 20}
   122    134   do_test rtree-1.4.3 {
   123    135     execsql { DROP TABLE t1 }
   124    136   } {}
   125    137   
   126    138   # Test that it is possible to create an r-tree table with ridiculous
   127    139   # column names.
   128    140   #
   129    141   do_test rtree-1.5.1 {
   130         -  execsql {
          142  +  execsql_intout {
   131    143       CREATE VIRTUAL TABLE t1 USING rtree("the key", "x dim.", "x2'dim");
   132    144       INSERT INTO t1 VALUES(1, 2, 3);
   133    145       SELECT "the key", "x dim.", "x2'dim" FROM t1;
   134    146     }
   135         -} {1 2.0 3.0}
          147  +} {1 2 3}
   136    148   do_test rtree-1.5.1 {
   137    149     execsql { DROP TABLE t1 }
   138    150   } {}
   139    151   
   140    152   # Force the r-tree constructor to fail.
   141    153   #
   142    154   do_test rtree-1.6.1 {
................................................................................
   157    169       CREATE VIRTUAL TABLE t1 USING rtree(ii, x1, x2, y1, y2);
   158    170       SELECT * FROM t1;
   159    171     }
   160    172   } {}
   161    173   
   162    174   do_test rtree-2.1.2 {
   163    175     execsql { INSERT INTO t1 VALUES(NULL, 1, 3, 2, 4) }
   164         -  execsql { SELECT * FROM t1 }
   165         -} {1 1.0 3.0 2.0 4.0}
          176  +  execsql_intout { SELECT * FROM t1 }
          177  +} {1 1 3 2 4}
   166    178   do_test rtree-2.1.3 {
   167    179     execsql { INSERT INTO t1 VALUES(NULL, 1, 3, 2, 4) }
   168    180     execsql { SELECT rowid FROM t1 ORDER BY rowid }
   169    181   } {1 2}
   170    182   do_test rtree-2.1.3 {
   171    183     execsql { INSERT INTO t1 VALUES(NULL, 1, 3, 2, 4) }
   172    184     execsql { SELECT ii FROM t1 ORDER BY ii }
................................................................................
   197    209   do_test rtree-3.1.1 {
   198    210     execsql { 
   199    211       CREATE VIRTUAL TABLE t1 USING rtree(ii, x1, x2, y1, y2);
   200    212       SELECT * FROM t1;
   201    213     }
   202    214   } {}
   203    215   do_test rtree-3.1.2 {
   204         -  execsql { 
          216  +  execsql_intout { 
   205    217       INSERT INTO t1 VALUES(5, 1, 3, 2, 4);
   206    218       SELECT * FROM t1;
   207    219     }
   208         -} {5 1.0 3.0 2.0 4.0}
          220  +} {5 1 3 2 4}
   209    221   do_test rtree-3.1.3 {
   210         -  execsql {
          222  +  execsql_intout {
   211    223       INSERT INTO t1 VALUES(6, 2, 6, 4, 8);
   212    224       SELECT * FROM t1;
   213    225     }
   214         -} {5 1.0 3.0 2.0 4.0 6 2.0 6.0 4.0 8.0}
          226  +} {5 1 3 2 4 6 2 6 4 8}
   215    227   
   216    228   # Test the constraint on the coordinates (c[i]<=c[i+1] where (i%2==0)):
   217    229   do_test rtree-3.2.1 {
   218    230     catchsql { INSERT INTO t1 VALUES(7, 2, 6, 4, 3) }
   219    231   } {1 {constraint failed}}
   220    232   do_test rtree-3.2.2 {
   221    233     catchsql { INSERT INTO t1 VALUES(8, 2, 6, 3, 3) }
................................................................................
   224    236   #----------------------------------------------------------------------------
   225    237   # Test cases rtree-5.* test DELETE operations.
   226    238   #
   227    239   do_test rtree-5.1.1 {
   228    240     execsql { CREATE VIRTUAL TABLE t2 USING rtree(ii, x1, x2) }
   229    241   } {}
   230    242   do_test rtree-5.1.2 {
   231         -  execsql { 
          243  +  execsql_intout { 
   232    244       INSERT INTO t2 VALUES(1, 10, 20);
   233    245       INSERT INTO t2 VALUES(2, 30, 40);
   234    246       INSERT INTO t2 VALUES(3, 50, 60);
   235    247       SELECT * FROM t2 ORDER BY ii;
   236    248     }
   237         -} {1 10.0 20.0 2 30.0 40.0 3 50.0 60.0}
          249  +} {1 10 20 2 30 40 3 50 60}
   238    250   do_test rtree-5.1.3 {
   239         -  execsql { 
          251  +  execsql_intout { 
   240    252       DELETE FROM t2 WHERE ii=2;
   241    253       SELECT * FROM t2 ORDER BY ii;
   242    254     }
   243         -} {1 10.0 20.0 3 50.0 60.0}
          255  +} {1 10 20 3 50 60}
   244    256   do_test rtree-5.1.4 {
   245         -  execsql { 
          257  +  execsql_intout { 
   246    258       DELETE FROM t2 WHERE ii=1;
   247    259       SELECT * FROM t2 ORDER BY ii;
   248    260     }
   249         -} {3 50.0 60.0}
          261  +} {3 50 60}
   250    262   do_test rtree-5.1.5 {
   251    263     execsql { 
   252    264       DELETE FROM t2 WHERE ii=3;
   253    265       SELECT * FROM t2 ORDER BY ii;
   254    266     }
   255    267   } {}
   256    268   do_test rtree-5.1.6 {
................................................................................
   260    272   #----------------------------------------------------------------------------
   261    273   # Test cases rtree-5.* test UPDATE operations.
   262    274   #
   263    275   do_test rtree-6.1.1 {
   264    276     execsql { CREATE VIRTUAL TABLE t3 USING rtree(ii, x1, x2, y1, y2) }
   265    277   } {}
   266    278   do_test rtree-6.1.2 {
   267         -  execsql {
          279  +  execsql_intout {
   268    280       INSERT INTO t3 VALUES(1, 2, 3, 4, 5);
   269    281       UPDATE t3 SET x2=5;
   270    282       SELECT * FROM t3;
   271    283     }
   272         -} {1 2.0 5.0 4.0 5.0}
          284  +} {1 2 5 4 5}
   273    285   do_test rtree-6.1.3 {
   274    286     execsql { UPDATE t3 SET ii = 2 }
   275         -  execsql { SELECT * FROM t3 }
   276         -} {2 2.0 5.0 4.0 5.0}
          287  +  execsql_intout { SELECT * FROM t3 }
          288  +} {2 2 5 4 5}
   277    289   
   278    290   #----------------------------------------------------------------------------
   279    291   # Test cases rtree-7.* test rename operations.
   280    292   #
   281    293   do_test rtree-7.1.1 {
   282    294     execsql {
   283    295       CREATE VIRTUAL TABLE t4 USING rtree(ii, x1, x2, y1, y2, z1, z2);
   284    296       INSERT INTO t4 VALUES(1, 2, 3, 4, 5, 6, 7);
   285    297     }
   286    298   } {}
   287    299   do_test rtree-7.1.2 {
   288    300     execsql { ALTER TABLE t4 RENAME TO t5 }
   289         -  execsql { SELECT * FROM t5 }
   290         -} {1 2.0 3.0 4.0 5.0 6.0 7.0}
          301  +  execsql_intout { SELECT * FROM t5 }
          302  +} {1 2 3 4 5 6 7}
   291    303   do_test rtree-7.1.3 {
   292    304     db close
   293    305     sqlite3 db test.db
   294         -  execsql { SELECT * FROM t5 }
   295         -} {1 2.0 3.0 4.0 5.0 6.0 7.0}
          306  +  execsql_intout { SELECT * FROM t5 }
          307  +} {1 2 3 4 5 6 7}
   296    308   do_test rtree-7.1.4 {
   297    309     execsql { ALTER TABLE t5 RENAME TO 'raisara "one"'''}
   298         -  execsql { SELECT * FROM "raisara ""one""'" }
   299         -} {1 2.0 3.0 4.0 5.0 6.0 7.0}
          310  +  execsql_intout { SELECT * FROM "raisara ""one""'" }
          311  +} {1 2 3 4 5 6 7}
   300    312   do_test rtree-7.1.5 {
   301         -  execsql { SELECT * FROM 'raisara "one"''' }
   302         -} {1 2.0 3.0 4.0 5.0 6.0 7.0}
          313  +  execsql_intout { SELECT * FROM 'raisara "one"''' }
          314  +} {1 2 3 4 5 6 7}
   303    315   do_test rtree-7.1.6 {
   304    316     execsql { ALTER TABLE "raisara ""one""'" RENAME TO "abc 123" }
   305         -  execsql { SELECT * FROM "abc 123" }
   306         -} {1 2.0 3.0 4.0 5.0 6.0 7.0}
          317  +  execsql_intout { SELECT * FROM "abc 123" }
          318  +} {1 2 3 4 5 6 7}
   307    319   do_test rtree-7.1.7 {
   308    320     db close
   309    321     sqlite3 db test.db
   310         -  execsql { SELECT * FROM "abc 123" }
   311         -} {1 2.0 3.0 4.0 5.0 6.0 7.0}
          322  +  execsql_intout { SELECT * FROM "abc 123" }
          323  +} {1 2 3 4 5 6 7}
   312    324   
   313    325   # An error midway through a rename operation.
   314    326   do_test rtree-7.2.1 {
   315    327     execsql { 
   316    328       CREATE TABLE t4_node(a);
   317    329     }
   318    330     catchsql { ALTER TABLE "abc 123" RENAME TO t4 }
   319    331   } {1 {SQL logic error or missing database}}
   320    332   do_test rtree-7.2.2 {
   321         -  execsql { SELECT * FROM "abc 123" }
   322         -} {1 2.0 3.0 4.0 5.0 6.0 7.0}
          333  +  execsql_intout { SELECT * FROM "abc 123" }
          334  +} {1 2 3 4 5 6 7}
   323    335   do_test rtree-7.2.3 {
   324    336     execsql { 
   325    337       DROP TABLE t4_node;
   326    338       CREATE TABLE t4_rowid(a);
   327    339     }
   328    340     catchsql { ALTER TABLE "abc 123" RENAME TO t4 }
   329    341   } {1 {SQL logic error or missing database}}
   330    342   do_test rtree-7.2.4 {
   331    343     db close
   332    344     sqlite3 db test.db
   333         -  execsql { SELECT * FROM "abc 123" }
   334         -} {1 2.0 3.0 4.0 5.0 6.0 7.0}
          345  +  execsql_intout { SELECT * FROM "abc 123" }
          346  +} {1 2 3 4 5 6 7}
   335    347   do_test rtree-7.2.5 {
   336    348     execsql { DROP TABLE t4_rowid }
   337    349     execsql { ALTER TABLE "abc 123" RENAME TO t4 }
   338         -  execsql { SELECT * FROM t4 }
   339         -} {1 2.0 3.0 4.0 5.0 6.0 7.0}
          350  +  execsql_intout { SELECT * FROM t4 }
          351  +} {1 2 3 4 5 6 7}
   340    352   
   341    353   
   342    354   #----------------------------------------------------------------------------
   343    355   # Test cases rtree-8.*
   344    356   #
   345    357   
   346    358   # Test that the function to determine if a leaf cell is part of the

Changes to ext/rtree/rtree4.test.

    23     23   }
    24     24   
    25     25   set ::NROW 2500
    26     26   if {[info exists G(isquick)] && $G(isquick)} {
    27     27     set ::NROW 250
    28     28   }
    29     29   
    30         -# Return a floating point number between -X and X.
    31         -# 
    32         -proc rand {X} {
    33         -  return [expr {int((rand()-0.5)*1024.0*$X)/512.0}]
    34         -}
    35         -
    36         -# Return a positive floating point number less than or equal to X
    37         -#
    38         -proc randincr {X} {
    39         -  while 1 {
    40         -    set r [expr {int(rand()*$X*32.0)/32.0}]
    41         -    if {$r>0.0} {return $r}
           30  +ifcapable !rtree_int_only {
           31  +  # Return a floating point number between -X and X.
           32  +  # 
           33  +  proc rand {X} {
           34  +    return [expr {int((rand()-0.5)*1024.0*$X)/512.0}]
           35  +  }
           36  +  
           37  +  # Return a positive floating point number less than or equal to X
           38  +  #
           39  +  proc randincr {X} {
           40  +    while 1 {
           41  +      set r [expr {int(rand()*$X*32.0)/32.0}]
           42  +      if {$r>0.0} {return $r}
           43  +    }
           44  +  }
           45  +} else {
           46  +  # For rtree_int_only, return an number between -X and X.
           47  +  # 
           48  +  proc rand {X} {
           49  +    return [expr {int((rand()-0.5)*2*$X)}]
           50  +  }
           51  +  
           52  +  # Return a positive integer less than or equal to X
           53  +  #
           54  +  proc randincr {X} {
           55  +    while 1 {
           56  +      set r [expr {int(rand()*$X)+1}]
           57  +      if {$r>0} {return $r}
           58  +    }
    42     59     }
    43     60   }
    44         -
           61  +  
    45     62   # Scramble the $inlist into a random order.
    46     63   #
    47     64   proc scramble {inlist} {
    48     65     set y {}
    49     66     foreach x $inlist {
    50     67       lappend y [list [expr {rand()}] $x]
    51     68     }

Changes to ext/rtree/rtree5.test.

    45     45   do_test rtree5-1.6 { 
    46     46     execsql { SELECT x1==5.0 FROM t1 }
    47     47   } {1}
    48     48   
    49     49   do_test rtree5-1.7 { 
    50     50     execsql { SELECT count(*) FROM t1 WHERE x1==5 }
    51     51   } {1}
    52         -do_test rtree5-1.8 { 
    53         -  execsql { SELECT count(*) FROM t1 WHERE x1==5.2 }
    54         -} {0}
           52  +ifcapable !rtree_int_only {
           53  +  do_test rtree5-1.8 { 
           54  +    execsql { SELECT count(*) FROM t1 WHERE x1==5.2 }
           55  +  } {0}
           56  +}
    55     57   do_test rtree5-1.9 { 
    56     58     execsql { SELECT count(*) FROM t1 WHERE x1==5.0 }
    57     59   } {1}
    58     60   
    59     61   do_test rtree5-1.10 { 
    60     62     execsql { SELECT (1<<31)-5, (1<<31)-1, -1*(1<<31), -1*(1<<31)+5 }
    61     63   } {2147483643 2147483647 -2147483648 -2147483643}

Changes to ext/rtree/rtree6.test.

    12     12   #
    13     13   
    14     14   if {![info exists testdir]} {
    15     15     set testdir [file join [file dirname [info script]] .. .. test]
    16     16   } 
    17     17   source $testdir/tester.tcl
    18     18   
    19         -ifcapable !rtree {
           19  +ifcapable {!rtree || rtree_int_only} {
    20     20     finish_test
    21     21     return
    22     22   }
    23     23   
    24     24   #   Operator    Byte Value
    25     25   #   ----------------------
    26     26   #      =        0x41 ('A')

Changes to ext/rtree/rtree7.test.

    19     19   } 
    20     20   source $testdir/tester.tcl
    21     21   
    22     22   ifcapable !rtree||!vacuum {
    23     23     finish_test
    24     24     return
    25     25   }
           26  +
           27  +# Like execsql except display output as integer where that can be
           28  +# done without loss of information.
           29  +#
           30  +proc execsql_intout {sql} {
           31  +  set out {}
           32  +  foreach term [execsql $sql] {
           33  +    regsub {\.0$} $term {} term
           34  +    lappend out $term
           35  +  }
           36  +  return $out
           37  +}
    26     38   
    27     39   do_test rtree7-1.1 {
    28     40     execsql {
    29     41       PRAGMA page_size = 1024;
    30     42       CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2, y1, y2);
    31     43       INSERT INTO rt VALUES(1, 1, 2, 3, 4);
    32     44     }
    33     45   } {}
    34     46   do_test rtree7-1.2 {
    35         -  execsql { SELECT * FROM rt }
    36         -} {1 1.0 2.0 3.0 4.0}
           47  +  execsql_intout { SELECT * FROM rt }
           48  +} {1 1 2 3 4}
    37     49   do_test rtree7-1.3 {
    38         -  execsql { 
           50  +  execsql_intout { 
    39     51       PRAGMA page_size = 2048;
    40     52       VACUUM;
    41     53       SELECT * FROM rt;
    42     54     }
    43         -} {1 1.0 2.0 3.0 4.0}
           55  +} {1 1 2 3 4}
    44     56   do_test rtree7-1.4 {
    45     57     for {set i 2} {$i <= 51} {incr i} {
    46     58       execsql { INSERT INTO rt VALUES($i, 1, 2, 3, 4) }
    47     59     }
    48         -  execsql { SELECT sum(x1), sum(x2), sum(y1), sum(y2) FROM rt }
    49         -} {51.0 102.0 153.0 204.0}
           60  +  execsql_intout { SELECT sum(x1), sum(x2), sum(y1), sum(y2) FROM rt }
           61  +} {51 102 153 204}
    50     62   do_test rtree7-1.5 {
    51         -  execsql { 
           63  +  execsql_intout { 
    52     64       PRAGMA page_size = 512;
    53     65       VACUUM;
    54     66       SELECT sum(x1), sum(x2), sum(y1), sum(y2) FROM rt
    55     67     }
    56         -} {51.0 102.0 153.0 204.0}
           68  +} {51 102 153 204}
    57     69   
    58     70   finish_test

Changes to ext/rtree/rtree9.test.

    13     13   # 
    14     14   
    15     15   if {![info exists testdir]} {
    16     16     set testdir [file join [file dirname [info script]] .. .. test]
    17     17   } 
    18     18   source $testdir/tester.tcl
    19     19   ifcapable !rtree { finish_test ; return }
           20  +ifcapable rtree_int_only { finish_test; return }
    20     21   
    21     22   register_cube_geom db
    22     23   
    23     24   do_execsql_test rtree9-1.1 {
    24     25     CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2, y1, y2, z1, z2);
    25     26     INSERT INTO rt VALUES(1, 1, 2, 1, 2, 1, 2);
    26     27   } {}

Changes to ext/rtree/rtreeB.test.

    14     14   
    15     15   if {![info exists testdir]} {
    16     16     set testdir [file join [file dirname [info script]] .. .. test]
    17     17   } 
    18     18   source $testdir/tester.tcl
    19     19   ifcapable !rtree { finish_test ; return }
    20     20   
    21         -do_test rtreeB-1.1 {
    22         -  db eval {
    23         -    CREATE VIRTUAL TABLE t1 USING rtree(ii, x0, y0, x1, y1);
    24         -    INSERT INTO t1 VALUES(1073741824, 0.0, 0.0, 100.0, 100.0);
    25         -    INSERT INTO t1 VALUES(2147483646, 0.0, 0.0, 200.0, 200.0);
    26         -    INSERT INTO t1 VALUES(4294967296, 0.0, 0.0, 300.0, 300.0);
    27         -    INSERT INTO t1 VALUES(8589934592, 20.0, 20.0, 150.0, 150.0);
    28         -    INSERT INTO t1 VALUES(9223372036854775807, 150, 150, 400, 400);
    29         -    SELECT rtreenode(2, data) FROM t1_node;
    30         -  }
    31         -} {{{1073741824 0.000000 0.000000 100.000000 100.000000} {2147483646 0.000000 0.000000 200.000000 200.000000} {4294967296 0.000000 0.000000 300.000000 300.000000} {8589934592 20.000000 20.000000 150.000000 150.000000} {9223372036854775807 150.000000 150.000000 400.000000 400.000000}}}
    32         -
           21  +ifcapable rtree_int_only {
           22  +  do_test rtreeB-1.1-intonly {
           23  +    db eval {
           24  +      CREATE VIRTUAL TABLE t1 USING rtree(ii, x0, y0, x1, y1);
           25  +      INSERT INTO t1 VALUES(1073741824, 0.0, 0.0, 100.0, 100.0);
           26  +      INSERT INTO t1 VALUES(2147483646, 0.0, 0.0, 200.0, 200.0);
           27  +      INSERT INTO t1 VALUES(4294967296, 0.0, 0.0, 300.0, 300.0);
           28  +      INSERT INTO t1 VALUES(8589934592, 20.0, 20.0, 150.0, 150.0);
           29  +      INSERT INTO t1 VALUES(9223372036854775807, 150, 150, 400, 400);
           30  +      SELECT rtreenode(2, data) FROM t1_node;
           31  +    }
           32  +  } {{{1073741824 0 0 100 100} {2147483646 0 0 200 200} {4294967296 0 0 300 300} {8589934592 20 20 150 150} {9223372036854775807 150 150 400 400}}}
           33  +} else {  
           34  +  do_test rtreeB-1.1 {
           35  +    db eval {
           36  +      CREATE VIRTUAL TABLE t1 USING rtree(ii, x0, y0, x1, y1);
           37  +      INSERT INTO t1 VALUES(1073741824, 0.0, 0.0, 100.0, 100.0);
           38  +      INSERT INTO t1 VALUES(2147483646, 0.0, 0.0, 200.0, 200.0);
           39  +      INSERT INTO t1 VALUES(4294967296, 0.0, 0.0, 300.0, 300.0);
           40  +      INSERT INTO t1 VALUES(8589934592, 20.0, 20.0, 150.0, 150.0);
           41  +      INSERT INTO t1 VALUES(9223372036854775807, 150, 150, 400, 400);
           42  +      SELECT rtreenode(2, data) FROM t1_node;
           43  +    }
           44  +  } {{{1073741824 0.000000 0.000000 100.000000 100.000000} {2147483646 0.000000 0.000000 200.000000 200.000000} {4294967296 0.000000 0.000000 300.000000 300.000000} {8589934592 20.000000 20.000000 150.000000 150.000000} {9223372036854775807 150.000000 150.000000 400.000000 400.000000}}}
           45  +}
    33     46   
    34     47   finish_test

Changes to ext/rtree/sqlite3rtree.h.

    27     27   ** R-Tree geometry query as follows:
    28     28   **
    29     29   **   SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
    30     30   */
    31     31   int sqlite3_rtree_geometry_callback(
    32     32     sqlite3 *db,
    33     33     const char *zGeom,
    34         -  int (*xGeom)(sqlite3_rtree_geometry *, int nCoord, double *aCoord, int *pRes),
           34  +#ifdef SQLITE_RTREE_INT_ONLY
           35  +  int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes),
           36  +#else
           37  +  int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes),
           38  +#endif
    35     39     void *pContext
    36     40   );
    37     41   
    38     42   
    39     43   /*
    40     44   ** A pointer to a structure of the following type is passed as the first
    41     45   ** argument to callbacks registered using rtree_geometry_callback().

Changes to src/btree.c.

  7550   7550     if( pCheck->errMsg.mallocFailed ){
  7551   7551       pCheck->mallocFailed = 1;
  7552   7552     }
  7553   7553   }
  7554   7554   #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
  7555   7555   
  7556   7556   #ifndef SQLITE_OMIT_INTEGRITY_CHECK
         7557  +
         7558  +/*
         7559  +** Return non-zero if the bit in the IntegrityCk.aPgRef[] array that
         7560  +** corresponds to page iPg is already set.
         7561  +*/
         7562  +static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){
         7563  +  assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 );
         7564  +  return (pCheck->aPgRef[iPg/8] & (1 << (iPg & 0x07)));
         7565  +}
         7566  +
         7567  +/*
         7568  +** Set the bit in the IntegrityCk.aPgRef[] array that corresponds to page iPg.
         7569  +*/
         7570  +static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){
         7571  +  assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 );
         7572  +  pCheck->aPgRef[iPg/8] |= (1 << (iPg & 0x07));
         7573  +}
         7574  +
         7575  +
  7557   7576   /*
  7558   7577   ** Add 1 to the reference count for page iPage.  If this is the second
  7559   7578   ** reference to the page, add an error message to pCheck->zErrMsg.
  7560   7579   ** Return 1 if there are 2 ore more references to the page and 0 if
  7561   7580   ** if this is the first reference to the page.
  7562   7581   **
  7563   7582   ** Also check that the page number is in bounds.
................................................................................
  7564   7583   */
  7565   7584   static int checkRef(IntegrityCk *pCheck, Pgno iPage, char *zContext){
  7566   7585     if( iPage==0 ) return 1;
  7567   7586     if( iPage>pCheck->nPage ){
  7568   7587       checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage);
  7569   7588       return 1;
  7570   7589     }
  7571         -  if( pCheck->anRef[iPage]==1 ){
         7590  +  if( getPageReferenced(pCheck, iPage) ){
  7572   7591       checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage);
  7573   7592       return 1;
  7574   7593     }
  7575         -  return  (pCheck->anRef[iPage]++)>1;
         7594  +  setPageReferenced(pCheck, iPage);
         7595  +  return 0;
  7576   7596   }
  7577   7597   
  7578   7598   #ifndef SQLITE_OMIT_AUTOVACUUM
  7579   7599   /*
  7580   7600   ** Check that the entry in the pointer-map for page iChild maps to 
  7581   7601   ** page iParent, pointer type ptrType. If not, append an error message
  7582   7602   ** to pCheck.
................................................................................
  7944   7964     sCheck.nErr = 0;
  7945   7965     sCheck.mallocFailed = 0;
  7946   7966     *pnErr = 0;
  7947   7967     if( sCheck.nPage==0 ){
  7948   7968       sqlite3BtreeLeave(p);
  7949   7969       return 0;
  7950   7970     }
  7951         -  sCheck.anRef = sqlite3Malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) );
  7952         -  if( !sCheck.anRef ){
         7971  +
         7972  +  sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1);
         7973  +  if( !sCheck.aPgRef ){
  7953   7974       *pnErr = 1;
  7954   7975       sqlite3BtreeLeave(p);
  7955   7976       return 0;
  7956   7977     }
  7957         -  for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; }
  7958   7978     i = PENDING_BYTE_PAGE(pBt);
  7959         -  if( i<=sCheck.nPage ){
  7960         -    sCheck.anRef[i] = 1;
  7961         -  }
         7979  +  if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
  7962   7980     sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), 20000);
  7963   7981     sCheck.errMsg.useMalloc = 2;
  7964   7982   
  7965   7983     /* Check the integrity of the freelist
  7966   7984     */
  7967   7985     checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
  7968   7986               get4byte(&pBt->pPage1->aData[36]), "Main freelist: ");
................................................................................
  7979   7997       checkTreePage(&sCheck, aRoot[i], "List of tree roots: ", NULL, NULL);
  7980   7998     }
  7981   7999   
  7982   8000     /* Make sure every page in the file is referenced
  7983   8001     */
  7984   8002     for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
  7985   8003   #ifdef SQLITE_OMIT_AUTOVACUUM
  7986         -    if( sCheck.anRef[i]==0 ){
         8004  +    if( getPageReferenced(&sCheck, i)==0 ){
  7987   8005         checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
  7988   8006       }
  7989   8007   #else
  7990   8008       /* If the database supports auto-vacuum, make sure no tables contain
  7991   8009       ** references to pointer-map pages.
  7992   8010       */
  7993         -    if( sCheck.anRef[i]==0 && 
         8011  +    if( getPageReferenced(&sCheck, i)==0 && 
  7994   8012          (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
  7995   8013         checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
  7996   8014       }
  7997         -    if( sCheck.anRef[i]!=0 && 
         8015  +    if( getPageReferenced(&sCheck, i)!=0 && 
  7998   8016          (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
  7999   8017         checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i);
  8000   8018       }
  8001   8019   #endif
  8002   8020     }
  8003   8021   
  8004   8022     /* Make sure this analysis did not leave any unref() pages.
................................................................................
  8011   8029         nRef, sqlite3PagerRefcount(pBt->pPager)
  8012   8030       );
  8013   8031     }
  8014   8032   
  8015   8033     /* Clean  up and report errors.
  8016   8034     */
  8017   8035     sqlite3BtreeLeave(p);
  8018         -  sqlite3_free(sCheck.anRef);
         8036  +  sqlite3_free(sCheck.aPgRef);
  8019   8037     if( sCheck.mallocFailed ){
  8020   8038       sqlite3StrAccumReset(&sCheck.errMsg);
  8021   8039       *pnErr = sCheck.nErr+1;
  8022   8040       return 0;
  8023   8041     }
  8024   8042     *pnErr = sCheck.nErr;
  8025   8043     if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg);

Changes to src/btreeInt.h.

   627    627   #define ISAUTOVACUUM 0
   628    628   #endif
   629    629   
   630    630   
   631    631   /*
   632    632   ** This structure is passed around through all the sanity checking routines
   633    633   ** in order to keep track of some global state information.
          634  +**
          635  +** The aRef[] array is allocated so that there is 1 bit for each page in
          636  +** the database. As the integrity-check proceeds, for each page used in
          637  +** the database the corresponding bit is set. This allows integrity-check to 
          638  +** detect pages that are used twice and orphaned pages (both of which 
          639  +** indicate corruption).
   634    640   */
   635    641   typedef struct IntegrityCk IntegrityCk;
   636    642   struct IntegrityCk {
   637    643     BtShared *pBt;    /* The tree being checked out */
   638    644     Pager *pPager;    /* The associated pager.  Also accessible by pBt->pPager */
   639         -  int *anRef;       /* Number of times each page is referenced */
          645  +  u8 *aPgRef;       /* 1 bit per page in the db (see above) */
   640    646     Pgno nPage;       /* Number of pages in the database */
   641    647     int mxErr;        /* Stop accumulating errors when this reaches zero */
   642    648     int nErr;         /* Number of messages written to zErrMsg so far */
   643    649     int mallocFailed; /* A memory allocation error has occurred */
   644    650     StrAccum errMsg;  /* Accumulate the error message text here */
   645    651   };
   646    652   

Changes to src/build.c.

   533    533     /* Delete the Table structure itself.
   534    534     */
   535    535     sqliteDeleteColumnNames(db, pTable);
   536    536     sqlite3DbFree(db, pTable->zName);
   537    537     sqlite3DbFree(db, pTable->zColAff);
   538    538     sqlite3SelectDelete(db, pTable->pSelect);
   539    539   #ifndef SQLITE_OMIT_CHECK
   540         -  sqlite3ExprDelete(db, pTable->pCheck);
          540  +  sqlite3ExprListDelete(db, pTable->pCheck);
   541    541   #endif
   542    542   #ifndef SQLITE_OMIT_VIRTUALTABLE
   543    543     sqlite3VtabClear(db, pTable);
   544    544   #endif
   545    545     sqlite3DbFree(db, pTable);
   546    546   }
   547    547   
................................................................................
  1196   1196   /*
  1197   1197   ** Add a new CHECK constraint to the table currently under construction.
  1198   1198   */
  1199   1199   void sqlite3AddCheckConstraint(
  1200   1200     Parse *pParse,    /* Parsing context */
  1201   1201     Expr *pCheckExpr  /* The check expression */
  1202   1202   ){
  1203         -  sqlite3 *db = pParse->db;
  1204   1203   #ifndef SQLITE_OMIT_CHECK
  1205   1204     Table *pTab = pParse->pNewTable;
  1206   1205     if( pTab && !IN_DECLARE_VTAB ){
  1207         -    pTab->pCheck = sqlite3ExprAnd(db, pTab->pCheck, pCheckExpr);
         1206  +    pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr);
         1207  +    if( pParse->constraintName.n ){
         1208  +      sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1);
         1209  +    }
  1208   1210     }else
  1209   1211   #endif
  1210   1212     {
  1211         -    sqlite3ExprDelete(db, pCheckExpr);
         1213  +    sqlite3ExprDelete(pParse->db, pCheckExpr);
  1212   1214     }
  1213   1215   }
  1214   1216   
  1215   1217   /*
  1216   1218   ** Set the collation function of the most recently parsed table column
  1217   1219   ** to the CollSeq given.
  1218   1220   */
................................................................................
  1474   1476   
  1475   1477   #ifndef SQLITE_OMIT_CHECK
  1476   1478     /* Resolve names in all CHECK constraint expressions.
  1477   1479     */
  1478   1480     if( p->pCheck ){
  1479   1481       SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
  1480   1482       NameContext sNC;                /* Name context for pParse->pNewTable */
         1483  +    ExprList *pList;                /* List of all CHECK constraints */
         1484  +    int i;                          /* Loop counter */
  1481   1485   
  1482   1486       memset(&sNC, 0, sizeof(sNC));
  1483   1487       memset(&sSrc, 0, sizeof(sSrc));
  1484   1488       sSrc.nSrc = 1;
  1485   1489       sSrc.a[0].zName = p->zName;
  1486   1490       sSrc.a[0].pTab = p;
  1487   1491       sSrc.a[0].iCursor = -1;
  1488   1492       sNC.pParse = pParse;
  1489   1493       sNC.pSrcList = &sSrc;
  1490   1494       sNC.isCheck = 1;
  1491         -    if( sqlite3ResolveExprNames(&sNC, p->pCheck) ){
  1492         -      return;
         1495  +    pList = p->pCheck;
         1496  +    for(i=0; i<pList->nExpr; i++){
         1497  +      if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
         1498  +        return;
         1499  +      }
  1493   1500       }
  1494   1501     }
  1495   1502   #endif /* !defined(SQLITE_OMIT_CHECK) */
  1496   1503   
  1497   1504     /* If the db->init.busy is 1 it means we are reading the SQL off the
  1498   1505     ** "sqlite_master" or "sqlite_temp_master" table on the disk.
  1499   1506     ** So do not write to the disk again.  Extract the root page number

Changes to src/callback.c.

   218    218   }
   219    219   
   220    220   /* During the search for the best function definition, this procedure
   221    221   ** is called to test how well the function passed as the first argument
   222    222   ** matches the request for a function with nArg arguments in a system
   223    223   ** that uses encoding enc. The value returned indicates how well the
   224    224   ** request is matched. A higher value indicates a better match.
          225  +**
          226  +** If nArg is -1 that means to only return a match (non-zero) if p->nArg
          227  +** is also -1.  In other words, we are searching for a function that
          228  +** takes a variable number of arguments.
          229  +**
          230  +** If nArg is -2 that means that we are searching for any function 
          231  +** regardless of the number of arguments it uses, so return a positive
          232  +** match score for any
   225    233   **
   226    234   ** The returned value is always between 0 and 6, as follows:
   227    235   **
   228         -** 0: Not a match, or if nArg<0 and the function is has no implementation.
   229         -** 1: A variable arguments function that prefers UTF-8 when a UTF-16
   230         -**    encoding is requested, or vice versa.
   231         -** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
   232         -**    requested, or vice versa.
   233         -** 3: A variable arguments function using the same text encoding.
   234         -** 4: A function with the exact number of arguments requested that
   235         -**    prefers UTF-8 when a UTF-16 encoding is requested, or vice versa.
   236         -** 5: A function with the exact number of arguments requested that
   237         -**    prefers UTF-16LE when UTF-16BE is requested, or vice versa.
   238         -** 6: An exact match.
          236  +** 0: Not a match.
          237  +** 1: UTF8/16 conversion required and function takes any number of arguments.
          238  +** 2: UTF16 byte order change required and function takes any number of args.
          239  +** 3: encoding matches and function takes any number of arguments
          240  +** 4: UTF8/16 conversion required - argument count matches exactly
          241  +** 5: UTF16 byte order conversion required - argument count matches exactly
          242  +** 6: Perfect match:  encoding and argument count match exactly.
   239    243   **
          244  +** If nArg==(-2) then any function with a non-null xStep or xFunc is
          245  +** a perfect match and any function with both xStep and xFunc NULL is
          246  +** a non-match.
   240    247   */
   241         -static int matchQuality(FuncDef *p, int nArg, u8 enc){
   242         -  int match = 0;
   243         -  if( p->nArg==-1 || p->nArg==nArg 
   244         -   || (nArg==-1 && (p->xFunc!=0 || p->xStep!=0))
   245         -  ){
          248  +#define FUNC_PERFECT_MATCH 6  /* The score for a perfect match */
          249  +static int matchQuality(
          250  +  FuncDef *p,     /* The function we are evaluating for match quality */
          251  +  int nArg,       /* Desired number of arguments.  (-1)==any */
          252  +  u8 enc          /* Desired text encoding */
          253  +){
          254  +  int match;
          255  +
          256  +  /* nArg of -2 is a special case */
          257  +  if( nArg==(-2) ) return (p->xFunc==0 && p->xStep==0) ? 0 : FUNC_PERFECT_MATCH;
          258  +
          259  +  /* Wrong number of arguments means "no match" */
          260  +  if( p->nArg!=nArg && p->nArg>=0 ) return 0;
          261  +
          262  +  /* Give a better score to a function with a specific number of arguments
          263  +  ** than to function that accepts any number of arguments. */
          264  +  if( p->nArg==nArg ){
          265  +    match = 4;
          266  +  }else{
   246    267       match = 1;
   247         -    if( p->nArg==nArg || nArg==-1 ){
   248         -      match = 4;
   249         -    }
   250         -    if( enc==p->iPrefEnc ){
   251         -      match += 2;
   252         -    }
   253         -    else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) ||
   254         -             (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
   255         -      match += 1;
   256         -    }
   257    268     }
          269  +
          270  +  /* Bonus points if the text encoding matches */
          271  +  if( enc==p->iPrefEnc ){
          272  +    match += 2;  /* Exact encoding match */
          273  +  }else if( (enc & p->iPrefEnc & 2)!=0 ){
          274  +    match += 1;  /* Both are UTF16, but with different byte orders */
          275  +  }
          276  +
   258    277     return match;
   259    278   }
   260    279   
   261    280   /*
   262    281   ** Search a FuncDefHash for a function with the given name.  Return
   263    282   ** a pointer to the matching FuncDef if found, or 0 if there is no match.
   264    283   */
................................................................................
   306    325   ** Locate a user function given a name, a number of arguments and a flag
   307    326   ** indicating whether the function prefers UTF-16 over UTF-8.  Return a
   308    327   ** pointer to the FuncDef structure that defines that function, or return
   309    328   ** NULL if the function does not exist.
   310    329   **
   311    330   ** If the createFlag argument is true, then a new (blank) FuncDef
   312    331   ** structure is created and liked into the "db" structure if a
   313         -** no matching function previously existed.  When createFlag is true
   314         -** and the nArg parameter is -1, then only a function that accepts
   315         -** any number of arguments will be returned.
          332  +** no matching function previously existed.
   316    333   **
   317         -** If createFlag is false and nArg is -1, then the first valid
   318         -** function found is returned.  A function is valid if either xFunc
   319         -** or xStep is non-zero.
          334  +** If nArg is -2, then the first valid function found is returned.  A
          335  +** function is valid if either xFunc or xStep is non-zero.  The nArg==(-2)
          336  +** case is used to see if zName is a valid function name for some number
          337  +** of arguments.  If nArg is -2, then createFlag must be 0.
   320    338   **
   321    339   ** If createFlag is false, then a function with the required name and
   322    340   ** number of arguments may be returned even if the eTextRep flag does not
   323    341   ** match that requested.
   324    342   */
   325    343   FuncDef *sqlite3FindFunction(
   326    344     sqlite3 *db,       /* An open database */
   327    345     const char *zName, /* Name of the function.  Not null-terminated */
   328    346     int nName,         /* Number of characters in the name */
   329    347     int nArg,          /* Number of arguments.  -1 means any number */
   330    348     u8 enc,            /* Preferred text encoding */
   331         -  int createFlag     /* Create new entry if true and does not otherwise exist */
          349  +  u8 createFlag      /* Create new entry if true and does not otherwise exist */
   332    350   ){
   333    351     FuncDef *p;         /* Iterator variable */
   334    352     FuncDef *pBest = 0; /* Best match found so far */
   335    353     int bestScore = 0;  /* Score of best match */
   336    354     int h;              /* Hash value */
   337    355   
   338         -
          356  +  assert( nArg>=(-2) );
          357  +  assert( nArg>=(-1) || createFlag==0 );
   339    358     assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
   340    359     h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a);
   341    360   
   342    361     /* First search for a match amongst the application-defined functions.
   343    362     */
   344    363     p = functionSearch(&db->aFunc, h, zName, nName);
   345    364     while( p ){
................................................................................
   377    396       }
   378    397     }
   379    398   
   380    399     /* If the createFlag parameter is true and the search did not reveal an
   381    400     ** exact match for the name, number of arguments and encoding, then add a
   382    401     ** new entry to the hash table and return it.
   383    402     */
   384         -  if( createFlag && (bestScore<6 || pBest->nArg!=nArg) && 
          403  +  if( createFlag && bestScore<FUNC_PERFECT_MATCH && 
   385    404         (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
   386    405       pBest->zName = (char *)&pBest[1];
   387    406       pBest->nArg = (u16)nArg;
   388    407       pBest->iPrefEnc = enc;
   389    408       memcpy(pBest->zName, zName, nName);
   390    409       pBest->zName[nName] = 0;
   391    410       sqlite3FuncDefInsert(&db->aFunc, pBest);

Changes to src/expr.c.

   480    480   Expr *sqlite3PExpr(
   481    481     Parse *pParse,          /* Parsing context */
   482    482     int op,                 /* Expression opcode */
   483    483     Expr *pLeft,            /* Left operand */
   484    484     Expr *pRight,           /* Right operand */
   485    485     const Token *pToken     /* Argument token */
   486    486   ){
   487         -  Expr *p = sqlite3ExprAlloc(pParse->db, op, pToken, 1);
   488         -  sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
          487  +  Expr *p;
          488  +  if( op==TK_AND && pLeft && pRight ){
          489  +    /* Take advantage of short-circuit false optimization for AND */
          490  +    p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
          491  +  }else{
          492  +    p = sqlite3ExprAlloc(pParse->db, op, pToken, 1);
          493  +    sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
          494  +  }
   489    495     if( p ) {
   490    496       sqlite3ExprCheckHeight(pParse, p->nHeight);
   491    497     }
   492    498     return p;
   493    499   }
          500  +
          501  +/*
          502  +** Return 1 if an expression must be FALSE in all cases and 0 if the
          503  +** expression might be true.  This is an optimization.  If is OK to
          504  +** return 0 here even if the expression really is always false (a 
          505  +** false negative).  But it is a bug to return 1 if the expression
          506  +** might be true in some rare circumstances (a false positive.)
          507  +**
          508  +** Note that if the expression is part of conditional for a
          509  +** LEFT JOIN, then we cannot determine at compile-time whether or not
          510  +** is it true or false, so always return 0.
          511  +*/
          512  +static int exprAlwaysFalse(Expr *p){
          513  +  int v = 0;
          514  +  if( ExprHasProperty(p, EP_FromJoin) ) return 0;
          515  +  if( !sqlite3ExprIsInteger(p, &v) ) return 0;
          516  +  return v==0;
          517  +}
   494    518   
   495    519   /*
   496    520   ** Join two expressions using an AND operator.  If either expression is
   497    521   ** NULL, then just return the other expression.
          522  +**
          523  +** If one side or the other of the AND is known to be false, then instead
          524  +** of returning an AND expression, just return a constant expression with
          525  +** a value of false.
   498    526   */
   499    527   Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){
   500    528     if( pLeft==0 ){
   501    529       return pRight;
   502    530     }else if( pRight==0 ){
   503    531       return pLeft;
          532  +  }else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){
          533  +    sqlite3ExprDelete(db, pLeft);
          534  +    sqlite3ExprDelete(db, pRight);
          535  +    return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
   504    536     }else{
   505    537       Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0);
   506    538       sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight);
   507    539       return pNew;
   508    540     }
   509    541   }
   510    542   
................................................................................
  3742   3774     if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
  3743   3775     if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
  3744   3776     if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
  3745   3777     if( ExprHasProperty(pA, EP_IntValue) ){
  3746   3778       if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
  3747   3779         return 2;
  3748   3780       }
  3749         -  }else if( pA->op!=TK_COLUMN && pA->u.zToken ){
         3781  +  }else if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
  3750   3782       if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
  3751   3783       if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
  3752   3784         return 2;
  3753   3785       }
  3754   3786     }
  3755   3787     if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
  3756   3788     if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
................................................................................
  3778   3810       Expr *pExprA = pA->a[i].pExpr;
  3779   3811       Expr *pExprB = pB->a[i].pExpr;
  3780   3812       if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
  3781   3813       if( sqlite3ExprCompare(pExprA, pExprB) ) return 1;
  3782   3814     }
  3783   3815     return 0;
  3784   3816   }
         3817  +
         3818  +/*
         3819  +** This is the expression callback for sqlite3FunctionUsesOtherSrc().
         3820  +**
         3821  +** Determine if an expression references any table other than one of the
         3822  +** tables in pWalker->u.pSrcList and abort if it does.
         3823  +*/
         3824  +static int exprUsesOtherSrc(Walker *pWalker, Expr *pExpr){
         3825  +  if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){
         3826  +    int i;
         3827  +    SrcList *pSrc = pWalker->u.pSrcList;
         3828  +    for(i=0; i<pSrc->nSrc; i++){
         3829  +      if( pExpr->iTable==pSrc->a[i].iCursor ) return WRC_Continue;
         3830  +    }
         3831  +    return WRC_Abort;
         3832  +  }else{
         3833  +    return WRC_Continue;
         3834  +  }
         3835  +}
         3836  +
         3837  +/*
         3838  +** Determine if any of the arguments to the pExpr Function references
         3839  +** any SrcList other than pSrcList.  Return true if they do.  Return
         3840  +** false if pExpr has no argument or has only constant arguments or
         3841  +** only references tables named in pSrcList.
         3842  +*/
         3843  +static int sqlite3FunctionUsesOtherSrc(Expr *pExpr, SrcList *pSrcList){
         3844  +  Walker w;
         3845  +  assert( pExpr->op==TK_AGG_FUNCTION );
         3846  +  memset(&w, 0, sizeof(w));
         3847  +  w.xExprCallback = exprUsesOtherSrc;
         3848  +  w.u.pSrcList = pSrcList;
         3849  +  if( sqlite3WalkExprList(&w, pExpr->x.pList)!=WRC_Continue ) return 1;
         3850  +  return 0;
         3851  +}
  3785   3852   
  3786   3853   /*
  3787   3854   ** Add a new element to the pAggInfo->aCol[] array.  Return the index of
  3788   3855   ** the new element.  Return a negative number if malloc fails.
  3789   3856   */
  3790   3857   static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){
  3791   3858     int i;
................................................................................
  3894   3961               break;
  3895   3962             } /* endif pExpr->iTable==pItem->iCursor */
  3896   3963           } /* end loop over pSrcList */
  3897   3964         }
  3898   3965         return WRC_Prune;
  3899   3966       }
  3900   3967       case TK_AGG_FUNCTION: {
  3901         -      /* The pNC->nDepth==0 test causes aggregate functions in subqueries
  3902         -      ** to be ignored */
  3903         -      if( pNC->nDepth==0 ){
         3968  +      if( !sqlite3FunctionUsesOtherSrc(pExpr, pSrcList) ){
  3904   3969           /* Check to see if pExpr is a duplicate of another aggregate 
  3905   3970           ** function that is already in the pAggInfo structure
  3906   3971           */
  3907   3972           struct AggInfo_func *pItem = pAggInfo->aFunc;
  3908   3973           for(i=0; i<pAggInfo->nFunc; i++, pItem++){
  3909   3974             if( sqlite3ExprCompare(pItem->pExpr, pExpr)==0 ){
  3910   3975               break;
................................................................................
  3940   4005           return WRC_Prune;
  3941   4006         }
  3942   4007       }
  3943   4008     }
  3944   4009     return WRC_Continue;
  3945   4010   }
  3946   4011   static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
  3947         -  NameContext *pNC = pWalker->u.pNC;
  3948         -  if( pNC->nDepth==0 ){
  3949         -    pNC->nDepth++;
  3950         -    sqlite3WalkSelect(pWalker, pSelect);
  3951         -    pNC->nDepth--;
  3952         -    return WRC_Prune;
  3953         -  }else{
  3954         -    return WRC_Continue;
  3955         -  }
         4012  +  return WRC_Continue;
  3956   4013   }
  3957   4014   
  3958   4015   /*
  3959   4016   ** Analyze the given expression looking for aggregate functions and
  3960   4017   ** for variables that need to be added to the pParse->aAgg[] array.
  3961   4018   ** Make additional entries to the pParse->aAgg[] array as necessary.
  3962   4019   **
  3963   4020   ** This routine should only be called after the expression has been
  3964   4021   ** analyzed by sqlite3ResolveExprNames().
  3965   4022   */
  3966   4023   void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
  3967   4024     Walker w;
         4025  +  memset(&w, 0, sizeof(w));
  3968   4026     w.xExprCallback = analyzeAggregate;
  3969   4027     w.xSelectCallback = analyzeAggregatesInSelect;
  3970   4028     w.u.pNC = pNC;
  3971   4029     assert( pNC->pSrcList!=0 );
  3972   4030     sqlite3WalkExpr(&w, pExpr);
  3973   4031   }
  3974   4032   

Changes to src/insert.c.

  1153   1153     int nCol;           /* Number of columns */
  1154   1154     int onError;        /* Conflict resolution strategy */
  1155   1155     int j1;             /* Addresss of jump instruction */
  1156   1156     int j2 = 0, j3;     /* Addresses of jump instructions */
  1157   1157     int regData;        /* Register containing first data column */
  1158   1158     int iCur;           /* Table cursor number */
  1159   1159     Index *pIdx;         /* Pointer to one of the indices */
         1160  +  sqlite3 *db;         /* Database connection */
  1160   1161     int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
  1161   1162     int regOldRowid = (rowidChng && isUpdate) ? rowidChng : regRowid;
  1162   1163   
         1164  +  db = pParse->db;
  1163   1165     v = sqlite3GetVdbe(pParse);
  1164   1166     assert( v!=0 );
  1165   1167     assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  1166   1168     nCol = pTab->nCol;
  1167   1169     regData = regRowid + 1;
  1168   1170   
  1169   1171     /* Test all NOT NULL constraints.
................................................................................
  1188   1190         case OE_Abort:
  1189   1191           sqlite3MayAbort(pParse);
  1190   1192         case OE_Rollback:
  1191   1193         case OE_Fail: {
  1192   1194           char *zMsg;
  1193   1195           sqlite3VdbeAddOp3(v, OP_HaltIfNull,
  1194   1196                                     SQLITE_CONSTRAINT, onError, regData+i);
  1195         -        zMsg = sqlite3MPrintf(pParse->db, "%s.%s may not be NULL",
         1197  +        zMsg = sqlite3MPrintf(db, "%s.%s may not be NULL",
  1196   1198                                 pTab->zName, pTab->aCol[i].zName);
  1197   1199           sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
  1198   1200           break;
  1199   1201         }
  1200   1202         case OE_Ignore: {
  1201   1203           sqlite3VdbeAddOp2(v, OP_IsNull, regData+i, ignoreDest);
  1202   1204           break;
................................................................................
  1210   1212         }
  1211   1213       }
  1212   1214     }
  1213   1215   
  1214   1216     /* Test all CHECK constraints
  1215   1217     */
  1216   1218   #ifndef SQLITE_OMIT_CHECK
  1217         -  if( pTab->pCheck && (pParse->db->flags & SQLITE_IgnoreChecks)==0 ){
  1218         -    int allOk = sqlite3VdbeMakeLabel(v);
         1219  +  if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
         1220  +    ExprList *pCheck = pTab->pCheck;
  1219   1221       pParse->ckBase = regData;
  1220         -    sqlite3ExprIfTrue(pParse, pTab->pCheck, allOk, SQLITE_JUMPIFNULL);
  1221   1222       onError = overrideError!=OE_Default ? overrideError : OE_Abort;
  1222         -    if( onError==OE_Ignore ){
  1223         -      sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
  1224         -    }else{
  1225         -      if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
  1226         -      sqlite3HaltConstraint(pParse, onError, 0, 0);
         1223  +    for(i=0; i<pCheck->nExpr; i++){
         1224  +      int allOk = sqlite3VdbeMakeLabel(v);
         1225  +      sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
         1226  +      if( onError==OE_Ignore ){
         1227  +        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
         1228  +      }else{
         1229  +        char *zConsName = pCheck->a[i].zName;
         1230  +        if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
         1231  +        if( zConsName ){
         1232  +          zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
         1233  +        }else{
         1234  +          zConsName = 0;
         1235  +        }
         1236  +        sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
         1237  +      }
         1238  +      sqlite3VdbeResolveLabel(v, allOk);
  1227   1239       }
  1228         -    sqlite3VdbeResolveLabel(v, allOk);
  1229   1240     }
  1230   1241   #endif /* !defined(SQLITE_OMIT_CHECK) */
  1231   1242   
  1232   1243     /* If we have an INTEGER PRIMARY KEY, make sure the primary key
  1233   1244     ** of the new record does not previously exist.  Except, if this
  1234   1245     ** is an UPDATE and the primary key is not changing, that is OK.
  1235   1246     */
................................................................................
  1277   1288           **
  1278   1289           **   REPLACE INTO t(rowid) VALUES($newrowid)
  1279   1290           **
  1280   1291           ** to run without a statement journal if there are no indexes on the
  1281   1292           ** table.
  1282   1293           */
  1283   1294           Trigger *pTrigger = 0;
  1284         -        if( pParse->db->flags&SQLITE_RecTriggers ){
         1295  +        if( db->flags&SQLITE_RecTriggers ){
  1285   1296             pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
  1286   1297           }
  1287   1298           if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
  1288   1299             sqlite3MultiWrite(pParse);
  1289   1300             sqlite3GenerateRowDelete(
  1290   1301                 pParse, pTab, baseCur, regRowid, 0, pTrigger, OE_Replace
  1291   1302             );
................................................................................
  1366   1377         case OE_Fail: {
  1367   1378           int j;
  1368   1379           StrAccum errMsg;
  1369   1380           const char *zSep;
  1370   1381           char *zErr;
  1371   1382   
  1372   1383           sqlite3StrAccumInit(&errMsg, 0, 0, 200);
  1373         -        errMsg.db = pParse->db;
         1384  +        errMsg.db = db;
  1374   1385           zSep = pIdx->nColumn>1 ? "columns " : "column ";
  1375   1386           for(j=0; j<pIdx->nColumn; j++){
  1376   1387             char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
  1377   1388             sqlite3StrAccumAppend(&errMsg, zSep, -1);
  1378   1389             zSep = ", ";
  1379   1390             sqlite3StrAccumAppend(&errMsg, zCol, -1);
  1380   1391           }
................................................................................
  1390   1401           sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
  1391   1402           break;
  1392   1403         }
  1393   1404         default: {
  1394   1405           Trigger *pTrigger = 0;
  1395   1406           assert( onError==OE_Replace );
  1396   1407           sqlite3MultiWrite(pParse);
  1397         -        if( pParse->db->flags&SQLITE_RecTriggers ){
         1408  +        if( db->flags&SQLITE_RecTriggers ){
  1398   1409             pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
  1399   1410           }
  1400   1411           sqlite3GenerateRowDelete(
  1401   1412               pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace
  1402   1413           );
  1403   1414           seenReplace = 1;
  1404   1415           break;
................................................................................
  1720   1731         if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
  1721   1732       }
  1722   1733       if( pSrcIdx==0 ){
  1723   1734         return 0;    /* pDestIdx has no corresponding index in pSrc */
  1724   1735       }
  1725   1736     }
  1726   1737   #ifndef SQLITE_OMIT_CHECK
  1727         -  if( pDest->pCheck && sqlite3ExprCompare(pSrc->pCheck, pDest->pCheck) ){
         1738  +  if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck, pDest->pCheck) ){
  1728   1739       return 0;   /* Tables have different CHECK constraints.  Ticket #2252 */
  1729   1740     }
  1730   1741   #endif
  1731   1742   #ifndef SQLITE_OMIT_FOREIGN_KEY
  1732   1743     /* Disallow the transfer optimization if the destination table constains
  1733   1744     ** any foreign key constraints.  This is more restrictive than necessary.
  1734   1745     ** But the main beneficiary of the transfer optimization is the VACUUM 

Changes to src/os_unix.c.

   161    161   ** Default permissions when creating a new file
   162    162   */
   163    163   #ifndef SQLITE_DEFAULT_FILE_PERMISSIONS
   164    164   # define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
   165    165   #endif
   166    166   
   167    167   /*
   168         - ** Default permissions when creating auto proxy dir
   169         - */
          168  +** Default permissions when creating auto proxy dir
          169  +*/
   170    170   #ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS
   171    171   # define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755
   172    172   #endif
   173    173   
   174    174   /*
   175    175   ** Maximum supported path-length.
   176    176   */
................................................................................
   508    508       if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
   509    509     }
   510    510     return 0;
   511    511   }
   512    512   
   513    513   /*
   514    514   ** Invoke open().  Do so multiple times, until it either succeeds or
   515         -** files for some reason other than EINTR.
          515  +** fails for some reason other than EINTR.
   516    516   **
   517    517   ** If the file creation mode "m" is 0 then set it to the default for
   518    518   ** SQLite.  The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally
   519    519   ** 0644) as modified by the system umask.  If m is not 0, then
   520    520   ** make the file creation mode be exactly m ignoring the umask.
   521    521   **
   522    522   ** The m parameter will be non-zero only when creating -wal, -journal,
................................................................................
   524    524   ** permissions as their original database, unadulterated by the umask.
   525    525   ** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a
   526    526   ** transaction crashes and leaves behind hot journals, then any
   527    527   ** process that is able to write to the database will also be able to
   528    528   ** recover the hot journals.
   529    529   */
   530    530   static int robust_open(const char *z, int f, mode_t m){
   531         -  int rc;
          531  +  int fd;
   532    532     mode_t m2;
   533    533     mode_t origM = 0;
   534    534     if( m==0 ){
   535    535       m2 = SQLITE_DEFAULT_FILE_PERMISSIONS;
   536    536     }else{
   537    537       m2 = m;
   538    538       origM = osUmask(0);
   539    539     }
   540         -  do{ rc = osOpen(z,f,m2); }while( rc<0 && errno==EINTR );
          540  +  do{
          541  +#if defined(O_CLOEXEC)
          542  +    fd = osOpen(z,f|O_CLOEXEC,m2);
          543  +#else
          544  +    fd = osOpen(z,f,m2);
          545  +#endif
          546  +  }while( fd<0 && errno==EINTR );
   541    547     if( m ){
   542    548       osUmask(origM);
   543    549     }
   544         -  return rc;
          550  +#if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0)
          551  +  if( fd>=0 ) osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
          552  +#endif
          553  +  return fd;
   545    554   }
   546    555   
   547    556   /*
   548    557   ** Helper functions to obtain and relinquish the global mutex. The
   549    558   ** global mutex is used to protect the unixInodeInfo and
   550    559   ** vxworksFileId objects used by this file, all of which may be 
   551    560   ** shared by multiple threads.
................................................................................
  3332   3341   
  3333   3342     sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
  3334   3343     for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
  3335   3344     if( ii>0 ){
  3336   3345       zDirname[ii] = '\0';
  3337   3346       fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
  3338   3347       if( fd>=0 ){
  3339         -#ifdef FD_CLOEXEC
  3340         -      osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
  3341         -#endif
  3342   3348         OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
  3343   3349       }
  3344   3350     }
  3345   3351     *pFd = fd;
  3346   3352     return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname));
  3347   3353   }
  3348   3354   
................................................................................
  3417   3423     SimulateIOError( return SQLITE_IOERR_TRUNCATE );
  3418   3424   
  3419   3425     /* If the user has configured a chunk-size for this file, truncate the
  3420   3426     ** file so that it consists of an integer number of chunks (i.e. the
  3421   3427     ** actual file size after the operation may be larger than the requested
  3422   3428     ** size).
  3423   3429     */
  3424         -  if( pFile->szChunk ){
         3430  +  if( pFile->szChunk>0 ){
  3425   3431       nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
  3426   3432     }
  3427   3433   
  3428   3434     rc = robust_ftruncate(pFile->h, (off_t)nByte);
  3429   3435     if( rc ){
  3430   3436       pFile->lastErrno = errno;
  3431   3437       return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
................................................................................
  5179   5185     }
  5180   5186   #if SQLITE_ENABLE_LOCKING_STYLE
  5181   5187     else{
  5182   5188       p->openFlags = openFlags;
  5183   5189     }
  5184   5190   #endif
  5185   5191   
  5186         -#ifdef FD_CLOEXEC
  5187         -  osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
  5188         -#endif
  5189         -
  5190   5192     noLock = eType!=SQLITE_OPEN_MAIN_DB;
  5191   5193   
  5192   5194     
  5193   5195   #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
  5194   5196     if( fstatfs(fd, &fsInfo) == -1 ){
  5195   5197       ((unixFile*)pFile)->lastErrno = errno;
  5196   5198       robust_close(p, fd, __LINE__);

Changes to src/os_win.c.

   217    217   #  define SQLITE_WIN32_HAS_WIDE
   218    218   #endif
   219    219   
   220    220   #ifndef SYSCALL
   221    221   #  define SYSCALL sqlite3_syscall_ptr
   222    222   #endif
   223    223   
   224         -#if SQLITE_OS_WINCE
   225         -/*
   226         -** These macros are necessary because Windows CE does not natively support the
   227         -** Win32 APIs LockFile, UnlockFile, and LockFileEx.
   228         - */
   229         -
   230         -#  define LockFile(a,b,c,d,e)       winceLockFile(&a, b, c, d, e)
   231         -#  define UnlockFile(a,b,c,d,e)     winceUnlockFile(&a, b, c, d, e)
   232         -#  define LockFileEx(a,b,c,d,e,f)   winceLockFileEx(&a, b, c, d, e, f)
   233         -
   234         -/*
   235         -** These are the special syscall hacks for Windows CE.  The locking related
   236         -** defines here refer to the macros defined just above.
   237         - */
   238         -
   239         -#  define osLockFile                LockFile
   240         -#  define osUnlockFile              UnlockFile
   241         -#  define osLockFileEx              LockFileEx
   242         -#endif
   243         -
   244    224   /*
   245    225   ** This function is not available on Windows CE or WinRT.
   246    226    */
   247    227   
   248    228   #if SQLITE_OS_WINCE || SQLITE_OS_WINRT
   249    229   #  define osAreFileApisANSI()       1
   250    230   #endif
................................................................................
   745    725   #else
   746    726     { "GetFileInformationByHandleEx", (SYSCALL)0,                  0 },
   747    727   #endif
   748    728   
   749    729   #define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
   750    730           FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[63].pCurrent)
   751    731   
          732  +#if !SQLITE_OS_WINCE
   752    733     { "MapViewOfFileEx",         (SYSCALL)MapViewOfFileEx,         0 },
          734  +#else
          735  +  { "MapViewOfFileEx",         (SYSCALL)0,                       0 },
          736  +#endif
   753    737   
   754    738   #define osMapViewOfFileEx ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,SIZE_T, \
   755    739           LPVOID))aSyscall[64].pCurrent)
   756    740   
   757    741   #if SQLITE_OS_WINRT
   758    742     { "CreateFile2",             (SYSCALL)CreateFile2,             0 },
   759    743   #else
................................................................................
  1486   1470       sqlite3_log(SQLITE_IOERR, 
  1487   1471         "delayed %dms for lock/sharing conflict",
  1488   1472         win32IoerrRetryDelay*nRetry*(nRetry+1)/2
  1489   1473       );
  1490   1474     }
  1491   1475   }
  1492   1476   
  1493         -/*
  1494         -** Lock a file region.
  1495         -*/
  1496         -static BOOL winLockFile(
  1497         -  HANDLE hFile,
  1498         -  DWORD flags,
  1499         -  DWORD offsetLow,
  1500         -  DWORD offsetHigh,
  1501         -  DWORD numBytesLow,
  1502         -  DWORD numBytesHigh
  1503         -){
  1504         -  if( isNT() ){
  1505         -    OVERLAPPED ovlp;
  1506         -    memset(&ovlp, 0, sizeof(OVERLAPPED));
  1507         -    ovlp.Offset = offsetLow;
  1508         -    ovlp.OffsetHigh = offsetHigh;
  1509         -    return osLockFileEx(hFile, flags, 0, numBytesLow, numBytesHigh, &ovlp);
  1510         -  }else{
  1511         -    return osLockFile(hFile, offsetLow, offsetHigh, numBytesLow, numBytesHigh);
  1512         -  }
  1513         -}
  1514         -
  1515         -/*
  1516         -** Unlock a file region.
  1517         - */
  1518         -static BOOL winUnlockFile(
  1519         -  HANDLE hFile,
  1520         -  DWORD offsetLow,
  1521         -  DWORD offsetHigh,
  1522         -  DWORD numBytesLow,
  1523         -  DWORD numBytesHigh
  1524         -){
  1525         -  if( isNT() ){
  1526         -    OVERLAPPED ovlp;
  1527         -    memset(&ovlp, 0, sizeof(OVERLAPPED));
  1528         -    ovlp.Offset = offsetLow;
  1529         -    ovlp.OffsetHigh = offsetHigh;
  1530         -    return osUnlockFileEx(hFile, 0, numBytesLow, numBytesHigh, &ovlp);
  1531         -  }else{
  1532         -    return osUnlockFile(hFile, offsetLow, offsetHigh, numBytesLow, numBytesHigh);
  1533         -  }
  1534         -}
  1535         -
  1536   1477   #if SQLITE_OS_WINCE
  1537   1478   /*************************************************************************
  1538   1479   ** This section contains code for WinCE only.
  1539   1480   */
  1540   1481   /*
  1541   1482   ** Windows CE does not have a localtime() function.  So create a
  1542   1483   ** substitute.
................................................................................
  1699   1640     }
  1700   1641   }
  1701   1642   
  1702   1643   /* 
  1703   1644   ** An implementation of the LockFile() API of Windows for CE
  1704   1645   */
  1705   1646   static BOOL winceLockFile(
  1706         -  HANDLE *phFile,
         1647  +  LPHANDLE phFile,
  1707   1648     DWORD dwFileOffsetLow,
  1708   1649     DWORD dwFileOffsetHigh,
  1709   1650     DWORD nNumberOfBytesToLockLow,
  1710   1651     DWORD nNumberOfBytesToLockHigh
  1711   1652   ){
  1712   1653     winFile *pFile = HANDLE_TO_WINFILE(phFile);
  1713   1654     BOOL bReturn = FALSE;
................................................................................
  1763   1704     return bReturn;
  1764   1705   }
  1765   1706   
  1766   1707   /*
  1767   1708   ** An implementation of the UnlockFile API of Windows for CE
  1768   1709   */
  1769   1710   static BOOL winceUnlockFile(
  1770         -  HANDLE *phFile,
         1711  +  LPHANDLE phFile,
  1771   1712     DWORD dwFileOffsetLow,
  1772   1713     DWORD dwFileOffsetHigh,
  1773   1714     DWORD nNumberOfBytesToUnlockLow,
  1774   1715     DWORD nNumberOfBytesToUnlockHigh
  1775   1716   ){
  1776   1717     winFile *pFile = HANDLE_TO_WINFILE(phFile);
  1777   1718     BOOL bReturn = FALSE;
................................................................................
  1820   1761         bReturn = TRUE;
  1821   1762       }
  1822   1763     }
  1823   1764   
  1824   1765     winceMutexRelease(pFile->hMutex);
  1825   1766     return bReturn;
  1826   1767   }
  1827         -
  1828         -/*
  1829         -** An implementation of the LockFileEx() API of Windows for CE
  1830         -*/
  1831         -static BOOL winceLockFileEx(
  1832         -  HANDLE *phFile,
  1833         -  DWORD dwFlags,
  1834         -  DWORD dwReserved,
  1835         -  DWORD nNumberOfBytesToLockLow,
  1836         -  DWORD nNumberOfBytesToLockHigh,
  1837         -  LPOVERLAPPED lpOverlapped
  1838         -){
  1839         -  UNUSED_PARAMETER(dwReserved);
  1840         -  UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
  1841         -
  1842         -  /* If the caller wants a shared read lock, forward this call
  1843         -  ** to winceLockFile */
  1844         -  if (lpOverlapped->Offset == (DWORD)SHARED_FIRST &&
  1845         -      dwFlags == 1 &&
  1846         -      nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
  1847         -    return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
  1848         -  }
  1849         -  return FALSE;
  1850         -}
  1851   1768   /*
  1852   1769   ** End of the special code for wince
  1853   1770   *****************************************************************************/
  1854   1771   #endif /* SQLITE_OS_WINCE */
         1772  +
         1773  +/*
         1774  +** Lock a file region.
         1775  +*/
         1776  +static BOOL winLockFile(
         1777  +  LPHANDLE phFile,
         1778  +  DWORD flags,
         1779  +  DWORD offsetLow,
         1780  +  DWORD offsetHigh,
         1781  +  DWORD numBytesLow,
         1782  +  DWORD numBytesHigh
         1783  +){
         1784  +#if SQLITE_OS_WINCE
         1785  +  /*
         1786  +  ** NOTE: Windows CE is handled differently here due its lack of the Win32
         1787  +  **       API LockFile.
         1788  +  */
         1789  +  return winceLockFile(phFile, offsetLow, offsetHigh,
         1790  +                       numBytesLow, numBytesHigh);
         1791  +#else
         1792  +  if( isNT() ){
         1793  +    OVERLAPPED ovlp;
         1794  +    memset(&ovlp, 0, sizeof(OVERLAPPED));
         1795  +    ovlp.Offset = offsetLow;
         1796  +    ovlp.OffsetHigh = offsetHigh;
         1797  +    return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp);
         1798  +  }else{
         1799  +    return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
         1800  +                      numBytesHigh);
         1801  +  }
         1802  +#endif
         1803  +}
         1804  +
         1805  +/*
         1806  +** Unlock a file region.
         1807  + */
         1808  +static BOOL winUnlockFile(
         1809  +  LPHANDLE phFile,
         1810  +  DWORD offsetLow,
         1811  +  DWORD offsetHigh,
         1812  +  DWORD numBytesLow,
         1813  +  DWORD numBytesHigh
         1814  +){
         1815  +#if SQLITE_OS_WINCE
         1816  +  /*
         1817  +  ** NOTE: Windows CE is handled differently here due its lack of the Win32
         1818  +  **       API UnlockFile.
         1819  +  */
         1820  +  return winceUnlockFile(phFile, offsetLow, offsetHigh,
         1821  +                         numBytesLow, numBytesHigh);
         1822  +#else
         1823  +  if( isNT() ){
         1824  +    OVERLAPPED ovlp;
         1825  +    memset(&ovlp, 0, sizeof(OVERLAPPED));
         1826  +    ovlp.Offset = offsetLow;
         1827  +    ovlp.OffsetHigh = offsetHigh;
         1828  +    return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp);
         1829  +  }else{
         1830  +    return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
         1831  +                        numBytesHigh);
         1832  +  }
         1833  +#endif
         1834  +}
  1855   1835   
  1856   1836   /*****************************************************************************
  1857   1837   ** The next group of routines implement the I/O methods specified
  1858   1838   ** by the sqlite3_io_methods object.
  1859   1839   ******************************************************************************/
  1860   1840   
  1861   1841   /*
................................................................................
  1974   1954   */
  1975   1955   static int winRead(
  1976   1956     sqlite3_file *id,          /* File to read from */
  1977   1957     void *pBuf,                /* Write content into this buffer */
  1978   1958     int amt,                   /* Number of bytes to read */
  1979   1959     sqlite3_int64 offset       /* Begin reading at this offset */
  1980   1960   ){
         1961  +#if !SQLITE_OS_WINCE
  1981   1962     OVERLAPPED overlapped;          /* The offset for ReadFile. */
         1963  +#endif
  1982   1964     winFile *pFile = (winFile*)id;  /* file handle */
  1983   1965     DWORD nRead;                    /* Number of bytes actually read from file */
  1984   1966     int nRetry = 0;                 /* Number of retrys */
  1985   1967   
  1986   1968     assert( id!=0 );
  1987   1969     SimulateIOError(return SQLITE_IOERR_READ);
  1988   1970     OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype));
  1989   1971   
         1972  +#if SQLITE_OS_WINCE
         1973  +  if( seekWinFile(pFile, offset) ){
         1974  +    return SQLITE_FULL;
         1975  +  }
         1976  +  while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
         1977  +#else
  1990   1978     memset(&overlapped, 0, sizeof(OVERLAPPED));
  1991   1979     overlapped.Offset = (LONG)(offset & 0xffffffff);
  1992   1980     overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
  1993   1981     while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) &&
  1994   1982            osGetLastError()!=ERROR_HANDLE_EOF ){
         1983  +#endif
  1995   1984       DWORD lastErrno;
  1996   1985       if( retryIoerr(&nRetry, &lastErrno) ) continue;
  1997   1986       pFile->lastErrno = lastErrno;
  1998   1987       return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
  1999   1988                "winRead", pFile->zPath);
  2000   1989     }
  2001   1990     logIoerr(nRetry);
................................................................................
  2025   2014     assert( amt>0 );
  2026   2015     assert( pFile );
  2027   2016     SimulateIOError(return SQLITE_IOERR_WRITE);
  2028   2017     SimulateDiskfullError(return SQLITE_FULL);
  2029   2018   
  2030   2019     OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype));
  2031   2020   
         2021  +#if SQLITE_OS_WINCE
         2022  +  rc = seekWinFile(pFile, offset);
         2023  +  if( rc==0 ){
         2024  +#else
  2032   2025     {
         2026  +#endif
         2027  +#if !SQLITE_OS_WINCE
  2033   2028       OVERLAPPED overlapped;        /* The offset for WriteFile. */
         2029  +#endif
  2034   2030       u8 *aRem = (u8 *)pBuf;        /* Data yet to be written */
  2035   2031       int nRem = amt;               /* Number of bytes yet to be written */
  2036   2032       DWORD nWrite;                 /* Bytes written by each WriteFile() call */
  2037   2033       DWORD lastErrno = NO_ERROR;   /* Value returned by GetLastError() */
  2038   2034   
         2035  +#if !SQLITE_OS_WINCE
  2039   2036       memset(&overlapped, 0, sizeof(OVERLAPPED));
  2040   2037       overlapped.Offset = (LONG)(offset & 0xffffffff);
  2041   2038       overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
         2039  +#endif
  2042   2040   
  2043   2041       while( nRem>0 ){
         2042  +#if SQLITE_OS_WINCE
         2043  +      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
         2044  +#else
  2044   2045         if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
         2046  +#endif
  2045   2047           if( retryIoerr(&nRetry, &lastErrno) ) continue;
  2046   2048           break;
  2047   2049         }
  2048   2050         if( nWrite<=0 ){
  2049   2051           lastErrno = osGetLastError();
  2050   2052           break;
  2051   2053         }
         2054  +#if !SQLITE_OS_WINCE
  2052   2055         offset += nWrite;
  2053   2056         overlapped.Offset = (LONG)(offset & 0xffffffff);
  2054   2057         overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
         2058  +#endif
  2055   2059         aRem += nWrite;
  2056   2060         nRem -= nWrite;
  2057   2061       }
  2058   2062       if( nRem>0 ){
  2059   2063         pFile->lastErrno = lastErrno;
  2060   2064         rc = 1;
  2061   2065       }
................................................................................
  2254   2258   ** Acquire a reader lock.
  2255   2259   ** Different API routines are called depending on whether or not this
  2256   2260   ** is Win9x or WinNT.
  2257   2261   */
  2258   2262   static int getReadLock(winFile *pFile){
  2259   2263     int res;
  2260   2264     if( isNT() ){
  2261         -    res = winLockFile(pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0,
         2265  +#if SQLITE_OS_WINCE
         2266  +    /*
         2267  +    ** NOTE: Windows CE is handled differently here due its lack of the Win32
         2268  +    **       API LockFileEx.
         2269  +    */
         2270  +    res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0);
         2271  +#else
         2272  +    res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0,
  2262   2273                         SHARED_SIZE, 0);
         2274  +#endif
  2263   2275     }
  2264   2276   #ifdef SQLITE_WIN32_HAS_ANSI
  2265   2277     else{
  2266   2278       int lk;
  2267   2279       sqlite3_randomness(sizeof(lk), &lk);
  2268   2280       pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
  2269         -    res = winLockFile(pFile->h, SQLITE_LOCKFILE_FLAGS,
         2281  +    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
  2270   2282                         SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
  2271   2283     }
  2272   2284   #endif
  2273   2285     if( res == 0 ){
  2274   2286       pFile->lastErrno = osGetLastError();
  2275   2287       /* No need to log a failure to lock */
  2276   2288     }
................................................................................
  2280   2292   /*
  2281   2293   ** Undo a readlock
  2282   2294   */
  2283   2295   static int unlockReadLock(winFile *pFile){
  2284   2296     int res;
  2285   2297     DWORD lastErrno;
  2286   2298     if( isNT() ){
  2287         -    res = winUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
         2299  +    res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
  2288   2300     }
  2289   2301   #ifdef SQLITE_WIN32_HAS_ANSI
  2290   2302     else{
  2291         -    res = winUnlockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
         2303  +    res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
  2292   2304     }
  2293   2305   #endif
  2294   2306     if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
  2295   2307       pFile->lastErrno = lastErrno;
  2296   2308       winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
  2297   2309                "unlockReadLock", pFile->zPath);
  2298   2310     }
................................................................................
  2357   2369     */
  2358   2370     newLocktype = pFile->locktype;
  2359   2371     if(   (pFile->locktype==NO_LOCK)
  2360   2372        || (   (locktype==EXCLUSIVE_LOCK)
  2361   2373            && (pFile->locktype==RESERVED_LOCK))
  2362   2374     ){
  2363   2375       int cnt = 3;
  2364         -    while( cnt-->0 && (res = winLockFile(pFile->h, SQLITE_LOCKFILE_FLAGS,
         2376  +    while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
  2365   2377                                            PENDING_BYTE, 0, 1, 0))==0 ){
  2366   2378         /* Try 3 times to get the pending lock.  This is needed to work
  2367   2379         ** around problems caused by indexing and/or anti-virus software on
  2368   2380         ** Windows systems.
  2369   2381         ** If you are using this code as a model for alternative VFSes, do not
  2370   2382         ** copy this retry logic.  It is a hack intended for Windows only.
  2371   2383         */
................................................................................
  2390   2402       }
  2391   2403     }
  2392   2404   
  2393   2405     /* Acquire a RESERVED lock
  2394   2406     */
  2395   2407     if( locktype==RESERVED_LOCK && res ){
  2396   2408       assert( pFile->locktype==SHARED_LOCK );
  2397         -    res = winLockFile(pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
         2409  +    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
  2398   2410       if( res ){
  2399   2411         newLocktype = RESERVED_LOCK;
  2400   2412       }else{
  2401   2413         lastErrno = osGetLastError();
  2402   2414       }
  2403   2415     }
  2404   2416   
................................................................................
  2411   2423   
  2412   2424     /* Acquire an EXCLUSIVE lock
  2413   2425     */
  2414   2426     if( locktype==EXCLUSIVE_LOCK && res ){
  2415   2427       assert( pFile->locktype>=SHARED_LOCK );
  2416   2428       res = unlockReadLock(pFile);
  2417   2429       OSTRACE(("unreadlock = %d\n", res));
  2418         -    res = winLockFile(pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0,
         2430  +    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0,
  2419   2431                         SHARED_SIZE, 0);
  2420   2432       if( res ){
  2421   2433         newLocktype = EXCLUSIVE_LOCK;
  2422   2434       }else{
  2423   2435         lastErrno = osGetLastError();
  2424   2436         OSTRACE(("error-code = %d\n", lastErrno));
  2425   2437         getReadLock(pFile);
................................................................................
  2426   2438       }
  2427   2439     }
  2428   2440   
  2429   2441     /* If we are holding a PENDING lock that ought to be released, then
  2430   2442     ** release it now.
  2431   2443     */
  2432   2444     if( gotPendingLock && locktype==SHARED_LOCK ){
  2433         -    winUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
         2445  +    winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
  2434   2446     }
  2435   2447   
  2436   2448     /* Update the state of the lock has held in the file descriptor then
  2437   2449     ** return the appropriate result code.
  2438   2450     */
  2439   2451     if( res ){
  2440   2452       rc = SQLITE_OK;
................................................................................
  2460   2472     SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
  2461   2473   
  2462   2474     assert( id!=0 );
  2463   2475     if( pFile->locktype>=RESERVED_LOCK ){
  2464   2476       rc = 1;
  2465   2477       OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc));
  2466   2478     }else{
  2467         -    rc = winLockFile(pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
         2479  +    rc = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
  2468   2480       if( rc ){
  2469         -      winUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
         2481  +      winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
  2470   2482       }
  2471   2483       rc = !rc;
  2472   2484       OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc));
  2473   2485     }
  2474   2486     *pResOut = rc;
  2475   2487     return SQLITE_OK;
  2476   2488   }
................................................................................
  2492   2504     int rc = SQLITE_OK;
  2493   2505     assert( pFile!=0 );
  2494   2506     assert( locktype<=SHARED_LOCK );
  2495   2507     OSTRACE(("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
  2496   2508             pFile->locktype, pFile->sharedLockByte));
  2497   2509     type = pFile->locktype;
  2498   2510     if( type>=EXCLUSIVE_LOCK ){
  2499         -    winUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
         2511  +    winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
  2500   2512       if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
  2501   2513         /* This should never happen.  We should always be able to
  2502   2514         ** reacquire the read lock */
  2503   2515         rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
  2504   2516                  "winUnlock", pFile->zPath);
  2505   2517       }
  2506   2518     }
  2507   2519     if( type>=RESERVED_LOCK ){
  2508         -    winUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
         2520  +    winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
  2509   2521     }
  2510   2522     if( locktype==NO_LOCK && type>=SHARED_LOCK ){
  2511   2523       unlockReadLock(pFile);
  2512   2524     }
  2513   2525     if( type>=PENDING_LOCK ){
  2514         -    winUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
         2526  +    winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
  2515   2527     }
  2516   2528     pFile->locktype = (u8)locktype;
  2517   2529     return rc;
  2518   2530   }
  2519   2531   
  2520   2532   /*
  2521   2533   ** If *pArg is inititially negative then this is a query.  Set *pArg to
................................................................................
  2752   2764     int rc = 0;           /* Result code form Lock/UnlockFileEx() */
  2753   2765   
  2754   2766     /* Access to the winShmNode object is serialized by the caller */
  2755   2767     assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
  2756   2768   
  2757   2769     /* Release/Acquire the system-level lock */
  2758   2770     if( lockType==_SHM_UNLCK ){
  2759         -    rc = winUnlockFile(pFile->hFile.h, ofst, 0, nByte, 0);
         2771  +    rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0);
  2760   2772     }else{
  2761   2773       /* Initialize the locking parameters */
  2762   2774       DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
  2763   2775       if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
  2764         -    rc = winLockFile(pFile->hFile.h, dwFlags, ofst, 0, nByte, 0);
         2776  +    rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0);
  2765   2777     }
  2766   2778     
  2767   2779     if( rc!= 0 ){
  2768   2780       rc = SQLITE_OK;
  2769   2781     }else{
  2770   2782       pFile->lastErrno =  osGetLastError();
  2771   2783       rc = SQLITE_BUSY;

Changes to src/parse.y.

   269    269   typename(A) ::= typename(X) ids(Y). {A.z=X.z; A.n=Y.n+(int)(Y.z-X.z);}
   270    270   signed ::= plus_num.
   271    271   signed ::= minus_num.
   272    272   
   273    273   // "carglist" is a list of additional constraints that come after the
   274    274   // column name and column type in a CREATE TABLE statement.
   275    275   //
   276         -carglist ::= carglist carg.
          276  +carglist ::= carglist cname ccons.
   277    277   carglist ::= .
   278         -carg ::= CONSTRAINT nm ccons.
   279         -carg ::= ccons.
          278  +cname ::= CONSTRAINT nm(X).           {pParse->constraintName = X;}
          279  +cname ::= .                           {pParse->constraintName.n = 0;}
   280    280   ccons ::= DEFAULT term(X).            {sqlite3AddDefaultValue(pParse,&X);}
   281    281   ccons ::= DEFAULT LP expr(X) RP.      {sqlite3AddDefaultValue(pParse,&X);}
   282    282   ccons ::= DEFAULT PLUS term(X).       {sqlite3AddDefaultValue(pParse,&X);}
   283    283   ccons ::= DEFAULT MINUS(A) term(X).      {
   284    284     ExprSpan v;
   285    285     v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, X.pExpr, 0, 0);
   286    286     v.zStart = A.z;
................................................................................
   335    335   defer_subclause(A) ::= NOT DEFERRABLE init_deferred_pred_opt.     {A = 0;}
   336    336   defer_subclause(A) ::= DEFERRABLE init_deferred_pred_opt(X).      {A = X;}
   337    337   %type init_deferred_pred_opt {int}
   338    338   init_deferred_pred_opt(A) ::= .                       {A = 0;}
   339    339   init_deferred_pred_opt(A) ::= INITIALLY DEFERRED.     {A = 1;}
   340    340   init_deferred_pred_opt(A) ::= INITIALLY IMMEDIATE.    {A = 0;}
   341    341   
   342         -// For the time being, the only constraint we care about is the primary
   343         -// key and UNIQUE.  Both create indices.
   344         -//
   345    342   conslist_opt(A) ::= .                   {A.n = 0; A.z = 0;}
   346    343   conslist_opt(A) ::= COMMA(X) conslist.  {A = X;}
   347         -conslist ::= conslist COMMA tcons.
   348         -conslist ::= conslist tcons.
   349         -conslist ::= tcons.
   350         -tcons ::= CONSTRAINT nm.
          344  +conslist ::= conslist COMMA cname tcons.
          345  +conslist ::= cname tcons.
   351    346   tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R).
   352    347                                    {sqlite3AddPrimaryKey(pParse,X,R,I,0);}
   353    348   tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
   354    349                                    {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0);}
   355    350   tcons ::= CHECK LP expr(E) RP onconf.
   356    351                                    {sqlite3AddCheckConstraint(pParse,E.pExpr);}
   357    352   tcons ::= FOREIGN KEY LP idxlist(FA) RP

Changes to src/resolve.c.

   529    529   
   530    530         testcase( pExpr->op==TK_CONST_FUNC );
   531    531         assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
   532    532         zId = pExpr->u.zToken;
   533    533         nId = sqlite3Strlen30(zId);
   534    534         pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
   535    535         if( pDef==0 ){
   536         -        pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0);
          536  +        pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
   537    537           if( pDef==0 ){
   538    538             no_such_func = 1;
   539    539           }else{
   540    540             wrong_num_args = 1;
   541    541           }
   542    542         }else{
   543    543           is_agg = pDef->xFunc==0;

Changes to src/rowset.c.

    72     72   ** The number of rowset entries per allocation chunk.
    73     73   */
    74     74   #define ROWSET_ENTRY_PER_CHUNK  \
    75     75                          ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry))
    76     76   
    77     77   /*
    78     78   ** Each entry in a RowSet is an instance of the following object.
           79  +**
           80  +** This same object is reused to store a linked list of trees of RowSetEntry
           81  +** objects.  In that alternative use, pRight points to the next entry
           82  +** in the list, pLeft points to the tree, and v is unused.  The
           83  +** RowSet.pForest value points to the head of this forest list.
    79     84   */
    80     85   struct RowSetEntry {            
    81     86     i64 v;                        /* ROWID value for this entry */
    82     87     struct RowSetEntry *pRight;   /* Right subtree (larger entries) or list */
    83     88     struct RowSetEntry *pLeft;    /* Left subtree (smaller entries) */
    84     89   };
    85     90   
................................................................................
   101    106   */
   102    107   struct RowSet {
   103    108     struct RowSetChunk *pChunk;    /* List of all chunk allocations */
   104    109     sqlite3 *db;                   /* The database connection */
   105    110     struct RowSetEntry *pEntry;    /* List of entries using pRight */
   106    111     struct RowSetEntry *pLast;     /* Last entry on the pEntry list */
   107    112     struct RowSetEntry *pFresh;    /* Source of new entry objects */
   108         -  struct RowSetEntry *pTree;     /* Binary tree of entries */
          113  +  struct RowSetEntry *pForest;   /* List of binary trees of entries */
   109    114     u16 nFresh;                    /* Number of objects on pFresh */
   110         -  u8 isSorted;                   /* True if pEntry is sorted */
          115  +  u8 rsFlags;                    /* Various flags */
   111    116     u8 iBatch;                     /* Current insert batch */
   112    117   };
   113    118   
          119  +/*
          120  +** Allowed values for RowSet.rsFlags
          121  +*/
          122  +#define ROWSET_SORTED  0x01   /* True if RowSet.pEntry is sorted */
          123  +#define ROWSET_NEXT    0x02   /* True if sqlite3RowSetNext() has been called */
          124  +
   114    125   /*
   115    126   ** Turn bulk memory into a RowSet object.  N bytes of memory
   116    127   ** are available at pSpace.  The db pointer is used as a memory context
   117    128   ** for any subsequent allocations that need to occur.
   118    129   ** Return a pointer to the new RowSet object.
   119    130   **
   120    131   ** It must be the case that N is sufficient to make a Rowset.  If not
................................................................................
   127    138     RowSet *p;
   128    139     assert( N >= ROUND8(sizeof(*p)) );
   129    140     p = pSpace;
   130    141     p->pChunk = 0;
   131    142     p->db = db;
   132    143     p->pEntry = 0;
   133    144     p->pLast = 0;
   134         -  p->pTree = 0;
          145  +  p->pForest = 0;
   135    146     p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
   136    147     p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
   137         -  p->isSorted = 1;
          148  +  p->rsFlags = ROWSET_SORTED;
   138    149     p->iBatch = 0;
   139    150     return p;
   140    151   }
   141    152   
   142    153   /*
   143    154   ** Deallocate all chunks from a RowSet.  This frees all memory that
   144    155   ** the RowSet has allocated over its lifetime.  This routine is
................................................................................
   150    161       pNextChunk = pChunk->pNextChunk;
   151    162       sqlite3DbFree(p->db, pChunk);
   152    163     }
   153    164     p->pChunk = 0;
   154    165     p->nFresh = 0;
   155    166     p->pEntry = 0;
   156    167     p->pLast = 0;
   157         -  p->pTree = 0;
   158         -  p->isSorted = 1;
          168  +  p->pForest = 0;
          169  +  p->rsFlags = ROWSET_SORTED;
          170  +}
          171  +
          172  +/*
          173  +** Allocate a new RowSetEntry object that is associated with the
          174  +** given RowSet.  Return a pointer to the new and completely uninitialized
          175  +** objected.
          176  +**
          177  +** In an OOM situation, the RowSet.db->mallocFailed flag is set and this
          178  +** routine returns NULL.
          179  +*/
          180  +static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){
          181  +  assert( p!=0 );
          182  +  if( p->nFresh==0 ){
          183  +    struct RowSetChunk *pNew;
          184  +    pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew));
          185  +    if( pNew==0 ){
          186  +      return 0;
          187  +    }
          188  +    pNew->pNextChunk = p->pChunk;
          189  +    p->pChunk = pNew;
          190  +    p->pFresh = pNew->aEntry;
          191  +    p->nFresh = ROWSET_ENTRY_PER_CHUNK;
          192  +  }
          193  +  p->nFresh--;
          194  +  return p->pFresh++;
   159    195   }
   160    196   
   161    197   /*
   162    198   ** Insert a new value into a RowSet.
   163    199   **
   164    200   ** The mallocFailed flag of the database connection is set if a
   165    201   ** memory allocation fails.
   166    202   */
   167    203   void sqlite3RowSetInsert(RowSet *p, i64 rowid){
   168    204     struct RowSetEntry *pEntry;  /* The new entry */
   169    205     struct RowSetEntry *pLast;   /* The last prior entry */
   170         -  assert( p!=0 );
   171         -  if( p->nFresh==0 ){
   172         -    struct RowSetChunk *pNew;
   173         -    pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew));
   174         -    if( pNew==0 ){
   175         -      return;
   176         -    }
   177         -    pNew->pNextChunk = p->pChunk;
   178         -    p->pChunk = pNew;
   179         -    p->pFresh = pNew->aEntry;
   180         -    p->nFresh = ROWSET_ENTRY_PER_CHUNK;
   181         -  }
   182         -  pEntry = p->pFresh++;
   183         -  p->nFresh--;
          206  +
          207  +  /* This routine is never called after sqlite3RowSetNext() */
          208  +  assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
          209  +
          210  +  pEntry = rowSetEntryAlloc(p);
          211  +  if( pEntry==0 ) return;
   184    212     pEntry->v = rowid;
   185    213     pEntry->pRight = 0;
   186    214     pLast = p->pLast;
   187    215     if( pLast ){
   188         -    if( p->isSorted && rowid<=pLast->v ){
   189         -      p->isSorted = 0;
          216  +    if( (p->rsFlags & ROWSET_SORTED)!=0 && rowid<=pLast->v ){
          217  +      p->rsFlags &= ~ROWSET_SORTED;
   190    218       }
   191    219       pLast->pRight = pEntry;
   192    220     }else{
   193         -    assert( p->pEntry==0 ); /* Fires if INSERT after SMALLEST */
   194    221       p->pEntry = pEntry;
   195    222     }
   196    223     p->pLast = pEntry;
   197    224   }
   198    225   
   199    226   /*
   200    227   ** Merge two lists of RowSetEntry objects.  Remove duplicates.
   201    228   **
   202    229   ** The input lists are connected via pRight pointers and are 
   203    230   ** assumed to each already be in sorted order.
   204    231   */
   205         -static struct RowSetEntry *rowSetMerge(
          232  +static struct RowSetEntry *rowSetEntryMerge(
   206    233     struct RowSetEntry *pA,    /* First sorted list to be merged */
   207    234     struct RowSetEntry *pB     /* Second sorted list to be merged */
   208    235   ){
   209    236     struct RowSetEntry head;
   210    237     struct RowSetEntry *pTail;
   211    238   
   212    239     pTail = &head;
................................................................................
   232    259       assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v );
   233    260       pTail->pRight = pB;
   234    261     }
   235    262     return head.pRight;
   236    263   }
   237    264   
   238    265   /*
   239         -** Sort all elements on the pEntry list of the RowSet into ascending order.
          266  +** Sort all elements on the list of RowSetEntry objects into order of
          267  +** increasing v.
   240    268   */ 
   241         -static void rowSetSort(RowSet *p){
          269  +static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){
   242    270     unsigned int i;
   243         -  struct RowSetEntry *pEntry;
   244         -  struct RowSetEntry *aBucket[40];
          271  +  struct RowSetEntry *pNext, *aBucket[40];
   245    272   
   246         -  assert( p->isSorted==0 );
   247    273     memset(aBucket, 0, sizeof(aBucket));
   248         -  while( p->pEntry ){
   249         -    pEntry = p->pEntry;
   250         -    p->pEntry = pEntry->pRight;
   251         -    pEntry->pRight = 0;
          274  +  while( pIn ){
          275  +    pNext = pIn->pRight;
          276  +    pIn->pRight = 0;
   252    277       for(i=0; aBucket[i]; i++){
   253         -      pEntry = rowSetMerge(aBucket[i], pEntry);
          278  +      pIn = rowSetEntryMerge(aBucket[i], pIn);
   254    279         aBucket[i] = 0;
   255    280       }
   256         -    aBucket[i] = pEntry;
          281  +    aBucket[i] = pIn;
          282  +    pIn = pNext;
   257    283     }
   258         -  pEntry = 0;
          284  +  pIn = 0;
   259    285     for(i=0; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
   260         -    pEntry = rowSetMerge(pEntry, aBucket[i]);
          286  +    pIn = rowSetEntryMerge(pIn, aBucket[i]);
   261    287     }
   262         -  p->pEntry = pEntry;
   263         -  p->pLast = 0;
   264         -  p->isSorted = 1;
          288  +  return pIn;
   265    289   }
   266    290   
   267    291   
   268    292   /*
   269    293   ** The input, pIn, is a binary tree (or subtree) of RowSetEntry objects.
   270    294   ** Convert this tree into a linked list connected by the pRight pointers
   271    295   ** and return pointers to the first and last elements of the new list.
................................................................................
   351    375       p->pLeft = pLeft;
   352    376       p->pRight = rowSetNDeepTree(&pList, iDepth);
   353    377     }
   354    378     return p;
   355    379   }
   356    380   
   357    381   /*
   358         -** Convert the list in p->pEntry into a sorted list if it is not
   359         -** sorted already.  If there is a binary tree on p->pTree, then
   360         -** convert it into a list too and merge it into the p->pEntry list.
          382  +** Take all the entries on p->pEntry and on the trees in p->pForest and
          383  +** sort them all together into one big ordered list on p->pEntry.
          384  +**
          385  +** This routine should only be called once in the life of a RowSet.
   361    386   */
   362    387   static void rowSetToList(RowSet *p){
   363         -  if( !p->isSorted ){
   364         -    rowSetSort(p);
          388  +
          389  +  /* This routine is called only once */
          390  +  assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
          391  +
          392  +  if( (p->rsFlags & ROWSET_SORTED)==0 ){
          393  +    p->pEntry = rowSetEntrySort(p->pEntry);
   365    394     }
   366         -  if( p->pTree ){
   367         -    struct RowSetEntry *pHead, *pTail;
   368         -    rowSetTreeToList(p->pTree, &pHead, &pTail);
   369         -    p->pTree = 0;
   370         -    p->pEntry = rowSetMerge(p->pEntry, pHead);
          395  +
          396  +  /* While this module could theoretically support it, sqlite3RowSetNext()
          397  +  ** is never called after sqlite3RowSetText() for the same RowSet.  So
          398  +  ** there is never a forest to deal with.  Should this change, simply
          399  +  ** remove the assert() and the #if 0. */
          400  +  assert( p->pForest==0 );
          401  +#if 0
          402  +  while( p->pForest ){
          403  +    struct RowSetEntry *pTree = p->pForest->pLeft;
          404  +    if( pTree ){
          405  +      struct RowSetEntry *pHead, *pTail;
          406  +      rowSetTreeToList(pTree, &pHead, &pTail);
          407  +      p->pEntry = rowSetEntryMerge(p->pEntry, pHead);
          408  +    }
          409  +    p->pForest = p->pForest->pRight;
   371    410     }
          411  +#endif
          412  +  p->rsFlags |= ROWSET_NEXT;  /* Verify this routine is never called again */
   372    413   }
   373    414   
   374    415   /*
   375    416   ** Extract the smallest element from the RowSet.
   376    417   ** Write the element into *pRowid.  Return 1 on success.  Return
   377    418   ** 0 if the RowSet is already empty.
   378    419   **
   379    420   ** After this routine has been called, the sqlite3RowSetInsert()
   380    421   ** routine may not be called again.  
   381    422   */
   382    423   int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
   383         -  rowSetToList(p);
          424  +  assert( p!=0 );
          425  +
          426  +  /* Merge the forest into a single sorted list on first call */
          427  +  if( (p->rsFlags & ROWSET_NEXT)==0 ) rowSetToList(p);
          428  +
          429  +  /* Return the next entry on the list */
   384    430     if( p->pEntry ){
   385    431       *pRowid = p->pEntry->v;
   386    432       p->pEntry = p->pEntry->pRight;
   387    433       if( p->pEntry==0 ){
   388    434         sqlite3RowSetClear(p);
   389    435       }
   390    436       return 1;
................................................................................
   392    438       return 0;
   393    439     }
   394    440   }
   395    441   
   396    442   /*
   397    443   ** Check to see if element iRowid was inserted into the the rowset as
   398    444   ** part of any insert batch prior to iBatch.  Return 1 or 0.
          445  +**
          446  +** If this is the first test of a new batch and if there exist entires
          447  +** on pRowSet->pEntry, then sort those entires into the forest at
          448  +** pRowSet->pForest so that they can be tested.
   399    449   */
   400    450   int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 iRowid){
   401         -  struct RowSetEntry *p;
          451  +  struct RowSetEntry *p, *pTree;
          452  +
          453  +  /* This routine is never called after sqlite3RowSetNext() */
          454  +  assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 );
          455  +
          456  +  /* Sort entries into the forest on the first test of a new batch 
          457  +  */
   402    458     if( iBatch!=pRowSet->iBatch ){
   403         -    if( pRowSet->pEntry ){
   404         -      rowSetToList(pRowSet);
   405         -      pRowSet->pTree = rowSetListToTree(pRowSet->pEntry);
          459  +    p = pRowSet->pEntry;
          460  +    if( p ){
          461  +      struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
          462  +      if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){
          463  +        p = rowSetEntrySort(p);
          464  +      }
          465  +      for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
          466  +        ppPrevTree = &pTree->pRight;
          467  +        if( pTree->pLeft==0 ){
          468  +          pTree->pLeft = rowSetListToTree(p);
          469  +          break;
          470  +        }else{
          471  +          struct RowSetEntry *pAux, *pTail;
          472  +          rowSetTreeToList(pTree->pLeft, &pAux, &pTail);
          473  +          pTree->pLeft = 0;
          474  +          p = rowSetEntryMerge(pAux, p);
          475  +        }
          476  +      }
          477  +      if( pTree==0 ){
          478  +        *ppPrevTree = pTree = rowSetEntryAlloc(pRowSet);
          479  +        if( pTree ){
          480  +          pTree->v = 0;
          481  +          pTree->pRight = 0;
          482  +          pTree->pLeft = rowSetListToTree(p);
          483  +        }
          484  +      }
   406    485         pRowSet->pEntry = 0;
   407    486         pRowSet->pLast = 0;
          487  +      pRowSet->rsFlags |= ROWSET_SORTED;
   408    488       }
   409    489       pRowSet->iBatch = iBatch;
   410    490     }
   411         -  p = pRowSet->pTree;
   412         -  while( p ){
   413         -    if( p->v<iRowid ){
   414         -      p = p->pRight;
   415         -    }else if( p->v>iRowid ){
   416         -      p = p->pLeft;
   417         -    }else{
   418         -      return 1;
          491  +
          492  +  /* Test to see if the iRowid value appears anywhere in the forest.
          493  +  ** Return 1 if it does and 0 if not.
          494  +  */
          495  +  for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
          496  +    p = pTree->pLeft;
          497  +    while( p ){
          498  +      if( p->v<iRowid ){
          499  +        p = p->pRight;
          500  +      }else if( p->v>iRowid ){
          501  +        p = p->pLeft;
          502  +      }else{
          503  +        return 1;
          504  +      }
   419    505       }
   420    506     }
   421    507     return 0;
   422    508   }

Changes to src/select.c.

  1254   1254     int cnt;                    /* Index added to make the name unique */
  1255   1255     Column *aCol, *pCol;        /* For looping over result columns */
  1256   1256     int nCol;                   /* Number of columns in the result set */
  1257   1257     Expr *p;                    /* Expression for a single result column */
  1258   1258     char *zName;                /* Column name */
  1259   1259     int nName;                  /* Size of name in zName[] */
  1260   1260   
  1261         -  *pnCol = nCol = pEList ? pEList->nExpr : 0;
  1262         -  aCol = *paCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
  1263         -  if( aCol==0 ) return SQLITE_NOMEM;
         1261  +  if( pEList ){
         1262  +    nCol = pEList->nExpr;
         1263  +    aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
         1264  +    testcase( aCol==0 );
         1265  +  }else{
         1266  +    nCol = 0;
         1267  +    aCol = 0;
         1268  +  }
         1269  +  *pnCol = nCol;
         1270  +  *paCol = aCol;
         1271  +
  1264   1272     for(i=0, pCol=aCol; i<nCol; i++, pCol++){
  1265   1273       /* Get an appropriate name for the column
  1266   1274       */
  1267   1275       p = pEList->a[i].pExpr;
  1268   1276       assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
  1269   1277                  || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
  1270   1278       if( (zName = pEList->a[i].zName)!=0 ){
................................................................................
  2839   2847       }
  2840   2848     }
  2841   2849   
  2842   2850     /***** If we reach this point, flattening is permitted. *****/
  2843   2851   
  2844   2852     /* Authorize the subquery */
  2845   2853     pParse->zAuthContext = pSubitem->zName;
  2846         -  sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
         2854  +  TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
         2855  +  testcase( i==SQLITE_DENY );
  2847   2856     pParse->zAuthContext = zSavedAuthContext;
  2848   2857   
  2849   2858     /* If the sub-query is a compound SELECT statement, then (by restrictions
  2850   2859     ** 17 and 18 above) it must be a UNION ALL and the parent query must 
  2851   2860     ** be of the form:
  2852   2861     **
  2853   2862     **     SELECT <expr-list> FROM (<sub-query>) <where-clause> 

Changes to src/shell.c.

   417    417   */
   418    418   struct callback_data {
   419    419     sqlite3 *db;           /* The database */
   420    420     int echoOn;            /* True to echo input commands */
   421    421     int statsOn;           /* True to display memory stats before each finalize */
   422    422     int cnt;               /* Number of records displayed so far */
   423    423     FILE *out;             /* Write results here */
          424  +  FILE *traceOut;        /* Output for sqlite3_trace() */
   424    425     int nErr;              /* Number of errors seen */
   425    426     int mode;              /* An output mode setting */
   426    427     int writableSchema;    /* True if PRAGMA writable_schema=ON */
   427    428     int showHeader;        /* True to show column names in List or Column mode */
   428    429     char *zDestTable;      /* Name of destination table when MODE_Insert */
   429    430     char separator[20];    /* Separator character for MODE_List */
   430    431     int colWidth[100];     /* Requested width of each column when in column mode*/
................................................................................
  1305   1306   
  1306   1307       zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
  1307   1308       /* Always quote the table name, even if it appears to be pure ascii,
  1308   1309       ** in case it is a keyword. Ex:  INSERT INTO "table" ... */
  1309   1310       zTmp = appendText(zTmp, zTable, '"');
  1310   1311       if( zTmp ){
  1311   1312         zSelect = appendText(zSelect, zTmp, '\'');
         1313  +      free(zTmp);
  1312   1314       }
  1313   1315       zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
  1314   1316       rc = sqlite3_step(pTableInfo);
  1315   1317       while( rc==SQLITE_ROW ){
  1316   1318         const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
  1317   1319         zSelect = appendText(zSelect, "quote(", 0);
  1318   1320         zSelect = appendText(zSelect, zText, '"');
................................................................................
  1333   1335       zSelect = appendText(zSelect, zTable, '"');
  1334   1336   
  1335   1337       rc = run_table_dump_query(p, zSelect, zPrepStmt);
  1336   1338       if( rc==SQLITE_CORRUPT ){
  1337   1339         zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
  1338   1340         run_table_dump_query(p, zSelect, 0);
  1339   1341       }
  1340         -    if( zSelect ) free(zSelect);
         1342  +    free(zSelect);
  1341   1343     }
  1342   1344     return 0;
  1343   1345   }
  1344   1346   
  1345   1347   /*
  1346   1348   ** Run zQuery.  Use dump_callback() as the callback routine so that
  1347   1349   ** the contents of the query are output as SQL statements.
................................................................................
  1363   1365       if( zErr ){
  1364   1366         fprintf(p->out, "/****** %s ******/\n", zErr);
  1365   1367         sqlite3_free(zErr);
  1366   1368         zErr = 0;
  1367   1369       }
  1368   1370       zQ2 = malloc( len+100 );
  1369   1371       if( zQ2==0 ) return rc;
  1370         -    sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
         1372  +    sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
  1371   1373       rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
  1372   1374       if( rc ){
  1373   1375         fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
  1374   1376       }else{
  1375   1377         rc = SQLITE_CORRUPT;
  1376   1378       }
  1377   1379       sqlite3_free(zErr);
................................................................................
  1429   1431     ".separator STRING      Change separator used by output mode and .import\n"
  1430   1432     ".show                  Show the current values for various settings\n"
  1431   1433     ".stats ON|OFF          Turn stats on or off\n"
  1432   1434     ".tables ?TABLE?        List names of tables\n"
  1433   1435     "                         If TABLE specified, only list tables matching\n"
  1434   1436     "                         LIKE pattern TABLE.\n"
  1435   1437     ".timeout MS            Try opening locked tables for MS milliseconds\n"
         1438  +  ".trace FILE|off        Output each SQL statement as it is run\n"
  1436   1439     ".vfsname ?AUX?         Print the name of the VFS stack\n"
  1437   1440     ".width NUM1 NUM2 ...   Set column widths for \"column\" mode\n"
  1438   1441   ;
  1439   1442   
  1440   1443   static char zTimerHelp[] =
  1441   1444     ".timer ON|OFF          Turn the CPU timer measurement on or off\n"
  1442   1445   ;
................................................................................
  1517   1520     if( strcmp(zArg,"on")==0 ){
  1518   1521       val = 1;
  1519   1522     }else if( strcmp(zArg,"yes")==0 ){
  1520   1523       val = 1;
  1521   1524     }
  1522   1525     return val;
  1523   1526   }
         1527  +
         1528  +/*
         1529  +** Close an output file, assuming it is not stderr or stdout
         1530  +*/
         1531  +static void output_file_close(FILE *f){
         1532  +  if( f && f!=stdout && f!=stderr ) fclose(f);
         1533  +}
         1534  +
         1535  +/*
         1536  +** Try to open an output file.   The names "stdout" and "stderr" are
         1537  +** recognized and do the right thing.  NULL is returned if the output 
         1538  +** filename is "off".
         1539  +*/
         1540  +static FILE *output_file_open(const char *zFile){
         1541  +  FILE *f;
         1542  +  if( strcmp(zFile,"stdout")==0 ){
         1543  +    f = stdout;
         1544  +  }else if( strcmp(zFile, "stderr")==0 ){
         1545  +    f = stderr;
         1546  +  }else if( strcmp(zFile, "off")==0 ){
         1547  +    f = 0;
         1548  +  }else{
         1549  +    f = fopen(zFile, "wb");
         1550  +    if( f==0 ){
         1551  +      fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
         1552  +    }
         1553  +  }
         1554  +  return f;
         1555  +}
         1556  +
         1557  +/*
         1558  +** A routine for handling output from sqlite3_trace().
         1559  +*/
         1560  +static void sql_trace_callback(void *pArg, const char *z){
         1561  +  FILE *f = (FILE*)pArg;
         1562  +  if( f ) fprintf(f, "%s\n", z);
         1563  +}
         1564  +
         1565  +/*
         1566  +** A no-op routine that runs with the ".breakpoint" doc-command.  This is
         1567  +** a useful spot to set a debugger breakpoint.
         1568  +*/
         1569  +static void test_breakpoint(void){
         1570  +  static int nCall = 0;
         1571  +  nCall++;
         1572  +}
  1524   1573   
  1525   1574   /*
  1526   1575   ** If an input line begins with "." then invoke this routine to
  1527   1576   ** process that line.
  1528   1577   **
  1529   1578   ** Return 1 on error, 2 to exit, and 0 otherwise.
  1530   1579   */
................................................................................
  1596   1645       }
  1597   1646       sqlite3_close(pDest);
  1598   1647     }else
  1599   1648   
  1600   1649     if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
  1601   1650       bail_on_error = booleanValue(azArg[1]);
  1602   1651     }else
         1652  +
         1653  +  /* The undocumented ".breakpoint" command causes a call to the no-op
         1654  +  ** routine named test_breakpoint().
         1655  +  */
         1656  +  if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
         1657  +    test_breakpoint();
         1658  +  }else
  1603   1659   
  1604   1660     if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
  1605   1661       struct callback_data data;
  1606   1662       char *zErrMsg = 0;
  1607   1663       open_db(p);
  1608   1664       memcpy(&data, p, sizeof(data));
  1609   1665       data.showHeader = 1;
................................................................................
  1928   1984         rc = 1;
  1929   1985       }
  1930   1986     }else
  1931   1987   #endif
  1932   1988   
  1933   1989     if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
  1934   1990       const char *zFile = azArg[1];
  1935         -    if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
  1936         -      fclose(p->pLog);
  1937         -      p->pLog = 0;
  1938         -    }
  1939         -    if( strcmp(zFile,"stdout")==0 ){
  1940         -      p->pLog = stdout;
  1941         -    }else if( strcmp(zFile, "stderr")==0 ){
  1942         -      p->pLog = stderr;
  1943         -    }else if( strcmp(zFile, "off")==0 ){
  1944         -      p->pLog = 0;
  1945         -    }else{
  1946         -      p->pLog = fopen(zFile, "w");
  1947         -      if( p->pLog==0 ){
  1948         -        fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
  1949         -      }
  1950         -    }
         1991  +    output_file_close(p->pLog);
         1992  +    p->pLog = output_file_open(zFile);
  1951   1993     }else
  1952   1994   
  1953   1995     if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
  1954   1996       int n2 = strlen30(azArg[1]);
  1955   1997       if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
  1956   1998           ||
  1957   1999           (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
................................................................................
  1996   2038   
  1997   2039     if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
  1998   2040       sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
  1999   2041                        "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
  2000   2042     }else
  2001   2043   
  2002   2044     if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
  2003         -    if( p->out!=stdout ){
  2004         -      if( p->outfile[0]=='|' ){
  2005         -        pclose(p->out);
  2006         -      }else{
  2007         -        fclose(p->out);
  2008         -      }
         2045  +    if( p->outfile[0]=='|' ){
         2046  +      pclose(p->out);
         2047  +    }else{
         2048  +      output_file_close(p->out);
  2009   2049       }
  2010         -    if( strcmp(azArg[1],"stdout")==0 ){
  2011         -      p->out = stdout;
  2012         -      sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
  2013         -    }else if( azArg[1][0]=='|' ){
         2050  +    p->outfile[0] = 0;
         2051  +    if( azArg[1][0]=='|' ){
  2014   2052         p->out = popen(&azArg[1][1], "w");
  2015   2053         if( p->out==0 ){
  2016   2054           fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]);
  2017   2055           p->out = stdout;
  2018   2056           rc = 1;
  2019   2057         }else{
  2020   2058           sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
  2021   2059         }
  2022   2060       }else{
  2023         -      p->out = fopen(azArg[1], "wb");
         2061  +      p->out = output_file_open(azArg[1]);
  2024   2062         if( p->out==0 ){
  2025         -        fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
         2063  +        if( strcmp(azArg[1],"off")!=0 ){
         2064  +          fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
         2065  +        }
  2026   2066           p->out = stdout;
  2027   2067           rc = 1;
  2028   2068         } else {
  2029         -         sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
         2069  +        sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
  2030   2070         }
  2031   2071       }
  2032   2072     }else
  2033   2073   
  2034   2074     if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
  2035   2075       if( nArg >= 2) {
  2036   2076         strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
................................................................................
  2392   2432       
  2393   2433     if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
  2394   2434      && nArg==2
  2395   2435     ){
  2396   2436       enableTimer = booleanValue(azArg[1]);
  2397   2437     }else
  2398   2438     
         2439  +  if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
         2440  +    output_file_close(p->traceOut);
         2441  +    p->traceOut = output_file_open(azArg[1]);
         2442  +#ifndef SQLITE_OMIT_TRACE
         2443  +    if( p->traceOut==0 ){
         2444  +      sqlite3_trace(p->db, 0, 0);
         2445  +    }else{
         2446  +      sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
         2447  +    }
         2448  +#endif
         2449  +  }else
         2450  +
  2399   2451     if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
  2400   2452       printf("SQLite %s %s\n" /*extra-version-info*/,
  2401   2453           sqlite3_libversion(), sqlite3_sourceid());
  2402   2454     }else
  2403   2455   
  2404   2456     if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
  2405   2457       const char *zDbName = nArg==2 ? azArg[1] : "main";
................................................................................
  2603   2655     }
  2604   2656     free(zLine);
  2605   2657     return errCnt;
  2606   2658   }
  2607   2659   
  2608   2660   /*
  2609   2661   ** Return a pathname which is the user's home directory.  A
  2610         -** 0 return indicates an error of some kind.  Space to hold the
  2611         -** resulting string is obtained from malloc().  The calling
  2612         -** function should free the result.
         2662  +** 0 return indicates an error of some kind.
  2613   2663   */
  2614   2664   static char *find_home_dir(void){
  2615         -  char *home_dir = NULL;
         2665  +  static char *home_dir = NULL;
         2666  +  if( home_dir ) return home_dir;
  2616   2667   
  2617   2668   #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
  2618   2669     struct passwd *pwent;
  2619   2670     uid_t uid = getuid();
  2620   2671     if( (pwent=getpwuid(uid)) != NULL) {
  2621   2672       home_dir = pwent->pw_dir;
  2622   2673     }
  2623   2674   #endif
  2624   2675   
  2625   2676   #if defined(_WIN32_WCE)
  2626   2677     /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
  2627   2678      */
  2628         -  home_dir = strdup("/");
         2679  +  home_dir = "/";
  2629   2680   #else
  2630   2681   
  2631   2682   #if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
  2632   2683     if (!home_dir) {
  2633   2684       home_dir = getenv("USERPROFILE");
  2634   2685     }
  2635   2686   #endif
................................................................................
  2677   2728     struct callback_data *p,        /* Configuration data */
  2678   2729     const char *sqliterc_override   /* Name of config file. NULL to use default */
  2679   2730   ){
  2680   2731     char *home_dir = NULL;
  2681   2732     const char *sqliterc = sqliterc_override;
  2682   2733     char *zBuf = 0;
  2683   2734     FILE *in = NULL;
  2684         -  int nBuf;
  2685   2735     int rc = 0;
  2686   2736   
  2687   2737     if (sqliterc == NULL) {
  2688   2738       home_dir = find_home_dir();
  2689   2739       if( home_dir==0 ){
  2690   2740   #if !defined(__RTP__) && !defined(_WRS_KERNEL)
  2691   2741         fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
  2692   2742   #endif
  2693   2743         return 1;
  2694   2744       }
  2695         -    nBuf = strlen30(home_dir) + 16;
  2696         -    zBuf = malloc( nBuf );
  2697         -    if( zBuf==0 ){
  2698         -      fprintf(stderr,"%s: Error: out of memory\n",Argv0);
  2699         -      return 1;
  2700         -    }
  2701         -    sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
  2702         -    free(home_dir);
  2703         -    sqliterc = (const char*)zBuf;
         2745  +    zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
         2746  +    sqliterc = zBuf;
  2704   2747     }
  2705   2748     in = fopen(sqliterc,"rb");
  2706   2749     if( in ){
  2707   2750       if( stdin_is_interactive ){
  2708   2751         fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
  2709   2752       }
  2710   2753       rc = process_input(p,in);
  2711   2754       fclose(in);
  2712   2755     }
  2713         -  free(zBuf);
         2756  +  sqlite3_free(zBuf);
  2714   2757     return rc;
  2715   2758   }
  2716   2759   
  2717   2760   /*
  2718   2761   ** Show available command line options
  2719   2762   */
  2720   2763   static const char zOptions[] = 
................................................................................
  3047   3090   #endif
  3048   3091         rc = process_input(&data, 0);
  3049   3092         if( zHistory ){
  3050   3093           stifle_history(100);
  3051   3094           write_history(zHistory);
  3052   3095           free(zHistory);
  3053   3096         }
  3054         -      free(zHome);
  3055   3097       }else{
  3056   3098         rc = process_input(&data, stdin);
  3057   3099       }
  3058   3100     }
  3059   3101     set_table_name(&data, 0);
  3060   3102     if( data.db ){
  3061   3103       sqlite3_close(data.db);
  3062   3104     }
  3063   3105     return rc;
  3064   3106   }

Changes to src/sqlite.h.in.

  1538   1538   ** connection is opened. If it is globally disabled, filenames are
  1539   1539   ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
  1540   1540   ** database connection is opened. By default, URI handling is globally
  1541   1541   ** disabled. The default value may be changed by compiling with the
  1542   1542   ** [SQLITE_USE_URI] symbol defined.
  1543   1543   **
  1544   1544   ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
  1545         -** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFNIG_GETPCACHE
         1545  +** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE
  1546   1546   ** <dd> These options are obsolete and should not be used by new code.
  1547   1547   ** They are retained for backwards compatibility but are now no-ops.
  1548   1548   ** </dl>
  1549   1549   */
  1550   1550   #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
  1551   1551   #define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
  1552   1552   #define SQLITE_CONFIG_SERIALIZED    3  /* nil */

Changes to src/sqliteInt.h.

  1277   1277     Select *pSelect;     /* NULL for tables.  Points to definition if a view. */
  1278   1278     u16 nRef;            /* Number of pointers to this Table */
  1279   1279     u8 tabFlags;         /* Mask of TF_* values */
  1280   1280     u8 keyConf;          /* What to do in case of uniqueness conflict on iPKey */
  1281   1281     FKey *pFKey;         /* Linked list of all foreign keys in this table */
  1282   1282     char *zColAff;       /* String defining the affinity of each column */
  1283   1283   #ifndef SQLITE_OMIT_CHECK
  1284         -  Expr *pCheck;        /* The AND of all CHECK constraints */
         1284  +  ExprList *pCheck;    /* All CHECK constraints */
  1285   1285   #endif
  1286   1286   #ifndef SQLITE_OMIT_ALTERTABLE
  1287   1287     int addColOffset;    /* Offset in CREATE TABLE stmt to add a new column */
  1288   1288   #endif
  1289   1289   #ifndef SQLITE_OMIT_VIRTUALTABLE
  1290   1290     VTable *pVTable;     /* List of VTable objects. */
  1291   1291     int nModuleArg;      /* Number of arguments to the module */
................................................................................
  2007   2007     SrcList *pSrcList;   /* One or more tables used to resolve names */
  2008   2008     ExprList *pEList;    /* Optional list of named expressions */
  2009   2009     int nRef;            /* Number of names resolved by this context */
  2010   2010     int nErr;            /* Number of errors encountered while resolving names */
  2011   2011     u8 allowAgg;         /* Aggregate functions allowed here */
  2012   2012     u8 hasAgg;           /* True if aggregates are seen */
  2013   2013     u8 isCheck;          /* True if resolving names in a CHECK constraint */
  2014         -  int nDepth;          /* Depth of subquery recursion. 1 for no recursion */
  2015   2014     AggInfo *pAggInfo;   /* Information about aggregates at this level */
  2016   2015     NameContext *pNext;  /* Next outer name context.  NULL for outermost */
  2017   2016   };
  2018   2017   
  2019   2018   /*
  2020   2019   ** An instance of the following structure contains all information
  2021   2020   ** needed to generate code for a single SELECT statement.
................................................................................
  2212   2211     yDbMask writeMask;   /* Start a write transaction on these databases */
  2213   2212     yDbMask cookieMask;  /* Bitmask of schema verified databases */
  2214   2213     int cookieGoto;      /* Address of OP_Goto to cookie verifier subroutine */
  2215   2214     int cookieValue[SQLITE_MAX_ATTACHED+2];  /* Values of cookies to verify */
  2216   2215     int regRowid;        /* Register holding rowid of CREATE TABLE entry */
  2217   2216     int regRoot;         /* Register holding root page number for new objects */
  2218   2217     int nMaxArg;         /* Max args passed to user function by sub-program */
         2218  +  Token constraintName;/* Name of the constraint currently being parsed */
  2219   2219   #ifndef SQLITE_OMIT_SHARED_CACHE
  2220   2220     int nTableLock;        /* Number of locks in aTableLock */
  2221   2221     TableLock *aTableLock; /* Required table locks for shared-cache mode */
  2222   2222   #endif
  2223   2223     AutoincInfo *pAinc;  /* Information about AUTOINCREMENT counters */
  2224   2224   
  2225   2225     /* Information used while coding trigger programs. */
................................................................................
  2472   2472   struct Walker {
  2473   2473     int (*xExprCallback)(Walker*, Expr*);     /* Callback for expressions */
  2474   2474     int (*xSelectCallback)(Walker*,Select*);  /* Callback for SELECTs */
  2475   2475     Parse *pParse;                            /* Parser context.  */
  2476   2476     union {                                   /* Extra data for callback */
  2477   2477       NameContext *pNC;                          /* Naming context */
  2478   2478       int i;                                     /* Integer value */
         2479  +    SrcList *pSrcList;                         /* FROM clause */
  2479   2480     } u;
  2480   2481   };
  2481   2482   
  2482   2483   /* Forward declarations */
  2483   2484   int sqlite3WalkExpr(Walker*, Expr*);
  2484   2485   int sqlite3WalkExprList(Walker*, ExprList*);
  2485   2486   int sqlite3WalkSelect(Walker*, Select*);
................................................................................
  2840   2841   void sqlite3HaltConstraint(Parse*, int, char*, int);
  2841   2842   Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
  2842   2843   ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
  2843   2844   SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
  2844   2845   IdList *sqlite3IdListDup(sqlite3*,IdList*);
  2845   2846   Select *sqlite3SelectDup(sqlite3*,Select*,int);
  2846   2847   void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
  2847         -FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,int);
         2848  +FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
  2848   2849   void sqlite3RegisterBuiltinFunctions(sqlite3*);
  2849   2850   void sqlite3RegisterDateTimeFunctions(void);
  2850   2851   void sqlite3RegisterGlobalFunctions(void);
  2851   2852   int sqlite3SafetyCheckOk(sqlite3*);
  2852   2853   int sqlite3SafetyCheckSickOrOk(sqlite3*);
  2853   2854   void sqlite3ChangeCookie(Parse*, int);
  2854   2855   

Changes to src/test1.c.

  3259   3259   #ifndef SQLITE_OMIT_UTF16
  3260   3260     sqlite3_stmt *pStmt;
  3261   3261     int idx;
  3262   3262     int bytes;
  3263   3263     char *value;
  3264   3264     int rc;
  3265   3265   
  3266         -  void (*xDel)() = (objc==6?SQLITE_STATIC:SQLITE_TRANSIENT);
         3266  +  void (*xDel)(void*) = (objc==6?SQLITE_STATIC:SQLITE_TRANSIENT);
  3267   3267     Tcl_Obj *oStmt    = objv[objc-4];
  3268   3268     Tcl_Obj *oN       = objv[objc-3];
  3269   3269     Tcl_Obj *oString  = objv[objc-2];
  3270   3270     Tcl_Obj *oBytes   = objv[objc-1];
  3271   3271   
  3272   3272     if( objc!=5 && objc!=6){
  3273   3273       Tcl_AppendResult(interp, "wrong # args: should be \"",
................................................................................
  3607   3607     rc = sqlite3_prepare(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0);
  3608   3608     Tcl_ResetResult(interp);
  3609   3609     if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
  3610   3610     if( zTail && objc>=5 ){
  3611   3611       if( bytes>=0 ){
  3612   3612         bytes = bytes - (zTail-zSql);
  3613   3613       }
  3614         -    if( strlen(zTail)<bytes ){
         3614  +    if( (int)strlen(zTail)<bytes ){
  3615   3615         bytes = strlen(zTail);
  3616   3616       }
  3617   3617       Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
  3618   3618     }
  3619   3619     if( rc!=SQLITE_OK ){
  3620   3620       assert( pStmt==0 );
  3621   3621       sprintf(zBuf, "(%d) ", rc);
................................................................................
  5812   5812     int ok;             /* Finished ok */
  5813   5813     int err;            /* True if an error occurs */
  5814   5814   };
  5815   5815   #endif
  5816   5816   
  5817   5817   
  5818   5818   #if SQLITE_OS_WIN
         5819  +#include <process.h>
  5819   5820   /*
  5820   5821   ** The background thread that does file locking.
  5821   5822   */
  5822   5823   static void win32_file_locker(void *pAppData){
  5823   5824     struct win32FileLocker *p = (struct win32FileLocker*)pAppData;
  5824   5825     if( p->evName ){
  5825   5826       HANDLE ev = OpenEvent(EVENT_MODIFY_STATE, FALSE, p->evName);
................................................................................
  6124   6125        { "sqlite3_column_name16",  test_stmt_utf16, (void*)sqlite3_column_name16},
  6125   6126        { "add_alignment_test_collations", add_alignment_test_collations, 0      },
  6126   6127   #ifndef SQLITE_OMIT_DECLTYPE
  6127   6128        { "sqlite3_column_decltype16",test_stmt_utf16,(void*)sqlite3_column_decltype16},
  6128   6129   #endif
  6129   6130   #ifdef SQLITE_ENABLE_COLUMN_METADATA
  6130   6131   {"sqlite3_column_database_name16",
  6131         -  test_stmt_utf16, sqlite3_column_database_name16},
         6132  +  test_stmt_utf16, (void*)sqlite3_column_database_name16},
  6132   6133   {"sqlite3_column_table_name16", test_stmt_utf16, (void*)sqlite3_column_table_name16},
  6133   6134   {"sqlite3_column_origin_name16", test_stmt_utf16, (void*)sqlite3_column_origin_name16},
  6134   6135   #endif
  6135   6136   #endif
  6136   6137        { "sqlite3_create_collation_v2", test_create_collation_v2, 0 },
  6137   6138        { "sqlite3_global_recover",     test_global_recover, 0   },
  6138   6139        { "working_64bit_int",          working_64bit_int,   0   },

Changes to src/test3.c.

   461    461     }
   462    462     if( Tcl_GetInt(interp, argv[1], (int*)&start) ) return TCL_ERROR;
   463    463     if( Tcl_GetInt(interp, argv[2], (int*)&mult) ) return TCL_ERROR;
   464    464     if( Tcl_GetInt(interp, argv[3], (int*)&count) ) return TCL_ERROR;
   465    465     if( Tcl_GetInt(interp, argv[4], (int*)&incr) ) return TCL_ERROR;
   466    466     in = start;
   467    467     in *= mult;
   468         -  for(i=0; i<count; i++){
          468  +  for(i=0; i<(int)count; i++){
   469    469       char zErr[200];
   470    470       n1 = putVarint(zBuf, in);
   471    471       if( n1>9 || n1<1 ){
   472    472         sprintf(zErr, "putVarint returned %d - should be between 1 and 9", n1);
   473    473         Tcl_AppendResult(interp, zErr, 0);
   474    474         return TCL_ERROR;
   475    475       }

Changes to src/test6.c.

   173    173   static int writeDbFile(CrashFile *p, u8 *z, i64 iAmt, i64 iOff){
   174    174     int rc = SQLITE_OK;
   175    175     int iSkip = 0;
   176    176     if( iOff==PENDING_BYTE && (p->flags&SQLITE_OPEN_MAIN_DB) ){
   177    177       iSkip = 512;
   178    178     }
   179    179     if( (iAmt-iSkip)>0 ){
   180         -    rc = sqlite3OsWrite(p->pRealFile, &z[iSkip], iAmt-iSkip, iOff+iSkip);
          180  +    rc = sqlite3OsWrite(p->pRealFile, &z[iSkip], (int)(iAmt-iSkip), iOff+iSkip);
   181    181     }
   182    182     return rc;
   183    183   }
   184    184   
   185    185   /*
   186    186   ** Flush the write-list as if xSync() had been called on file handle
   187    187   ** pFile. If isCrash is true, simulate a crash.
................................................................................
   302    302             );
   303    303           }
   304    304   #endif
   305    305           break;
   306    306         }
   307    307         case 3: {               /* Trash sectors */
   308    308           u8 *zGarbage;
   309         -        int iFirst = (pWrite->iOffset/g.iSectorSize);
   310         -        int iLast = (pWrite->iOffset+pWrite->nBuf-1)/g.iSectorSize;
          309  +        int iFirst = (int)(pWrite->iOffset/g.iSectorSize);
          310  +        int iLast = (int)((pWrite->iOffset+pWrite->nBuf-1)/g.iSectorSize);
   311    311   
   312    312           assert(pWrite->zBuf);
   313    313   
   314    314   #ifdef TRACE_CRASHTEST
   315    315           printf("Trashing %d sectors @ sector %d (%s)\n", 
   316    316               1+iLast-iFirst, iFirst, pWrite->pFile->zName
   317    317           );
................................................................................
   426    426     sqlite3_file *pFile, 
   427    427     const void *zBuf, 
   428    428     int iAmt, 
   429    429     sqlite_int64 iOfst
   430    430   ){
   431    431     CrashFile *pCrash = (CrashFile *)pFile;
   432    432     if( iAmt+iOfst>pCrash->iSize ){
   433         -    pCrash->iSize = iAmt+iOfst;
          433  +    pCrash->iSize = (int)(iAmt+iOfst);
   434    434     }
   435    435     while( pCrash->iSize>pCrash->nData ){
   436    436       u8 *zNew;
   437    437       int nNew = (pCrash->nData*2) + 4096;
   438    438       zNew = crash_realloc(pCrash->zData, nNew);
   439    439       if( !zNew ){
   440    440         return SQLITE_NOMEM;
................................................................................
   450    450   /*
   451    451   ** Truncate a crash-file.
   452    452   */
   453    453   static int cfTruncate(sqlite3_file *pFile, sqlite_int64 size){
   454    454     CrashFile *pCrash = (CrashFile *)pFile;
   455    455     assert(size>=0);
   456    456     if( pCrash->iSize>size ){
   457         -    pCrash->iSize = size;
          457  +    pCrash->iSize = (int)size;
   458    458     }
   459    459     return writeListAppend(pFile, size, 0, 0);
   460    460   }
   461    461   
   462    462   /*
   463    463   ** Sync a crash-file.
   464    464   */
................................................................................
   514    514   }
   515    515   static int cfFileControl(sqlite3_file *pFile, int op, void *pArg){
   516    516     if( op==SQLITE_FCNTL_SIZE_HINT ){
   517    517       CrashFile *pCrash = (CrashFile *)pFile;
   518    518       i64 nByte = *(i64 *)pArg;
   519    519       if( nByte>pCrash->iSize ){
   520    520         if( SQLITE_OK==writeListAppend(pFile, nByte, 0, 0) ){
   521         -        pCrash->iSize = nByte;
          521  +        pCrash->iSize = (int)nByte;
   522    522         }
   523    523       }
   524    524       return SQLITE_OK;
   525    525     }
   526    526     return sqlite3OsFileControl(((CrashFile *)pFile)->pRealFile, op, pArg);
   527    527   }
   528    528   
................................................................................
   631    631         */
   632    632         const int isDb = (flags&SQLITE_OPEN_MAIN_DB);
   633    633         i64 iChunk = pWrapper->iSize;
   634    634         if( iChunk>PENDING_BYTE && isDb ){
   635    635           iChunk = PENDING_BYTE;
   636    636         }
   637    637         memset(pWrapper->zData, 0, pWrapper->nData);
   638         -      rc = sqlite3OsRead(pReal, pWrapper->zData, iChunk, 0); 
          638  +      rc = sqlite3OsRead(pReal, pWrapper->zData, (int)iChunk, 0); 
   639    639         if( SQLITE_OK==rc && pWrapper->iSize>(PENDING_BYTE+512) && isDb ){
   640    640           i64 iOff = PENDING_BYTE+512;
   641    641           iChunk = pWrapper->iSize - iOff;
   642         -        rc = sqlite3OsRead(pReal, &pWrapper->zData[iOff], iChunk, iOff);
          642  +        rc = sqlite3OsRead(pReal, &pWrapper->zData[iOff], (int)iChunk, iOff);
   643    643         }
   644    644       }else{
   645    645         rc = SQLITE_NOMEM;
   646    646       }
   647    647     }
   648    648     if( rc!=SQLITE_OK && pWrapper->pMethod ){
   649    649       sqlite3OsClose(pFile);

Changes to src/test_config.c.

   421    421   #endif
   422    422   
   423    423   #ifdef SQLITE_ENABLE_RTREE
   424    424     Tcl_SetVar2(interp, "sqlite_options", "rtree", "1", TCL_GLOBAL_ONLY);
   425    425   #else
   426    426     Tcl_SetVar2(interp, "sqlite_options", "rtree", "0", TCL_GLOBAL_ONLY);
   427    427   #endif
          428  +
          429  +#ifdef SQLITE_RTREE_INT_ONLY
          430  +  Tcl_SetVar2(interp, "sqlite_options", "rtree_int_only", "1", TCL_GLOBAL_ONLY);
          431  +#else
          432  +  Tcl_SetVar2(interp, "sqlite_options", "rtree_int_only", "0", TCL_GLOBAL_ONLY);
          433  +#endif
   428    434   
   429    435   #ifdef SQLITE_OMIT_SCHEMA_PRAGMAS
   430    436     Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "0", TCL_GLOBAL_ONLY);
   431    437   #else
   432    438     Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "1", TCL_GLOBAL_ONLY);
   433    439   #endif
   434    440   

Changes to src/test_fuzzer.c.

  1123   1123     }
  1124   1124     pIdxInfo->estimatedCost = (double)10000;
  1125   1125      
  1126   1126     return SQLITE_OK;
  1127   1127   }
  1128   1128   
  1129   1129   /*
  1130         -** A virtual table module that provides read-only access to a
  1131         -** Tcl global variable namespace.
         1130  +** A virtual table module that implements the "fuzzer".
  1132   1131   */
  1133   1132   static sqlite3_module fuzzerModule = {
  1134   1133     0,                           /* iVersion */
  1135   1134     fuzzerConnect,
  1136   1135     fuzzerConnect,
  1137   1136     fuzzerBestIndex,
  1138   1137     fuzzerDisconnect, 

Changes to src/test_journal.c.

   400    400         }
   401    401         iTrunk = decodeUint32(aData);
   402    402       }
   403    403   
   404    404       /* Calculate and store a checksum for each page in the database file. */
   405    405       if( rc==SQLITE_OK ){
   406    406         int ii;
   407         -      for(ii=0; rc==SQLITE_OK && ii<pMain->nPage; ii++){
          407  +      for(ii=0; rc==SQLITE_OK && ii<(int)pMain->nPage; ii++){
   408    408           i64 iOff = (i64)(pMain->nPagesize) * (i64)ii;
   409    409           if( iOff==PENDING_BYTE ) continue;
   410    410           rc = sqlite3OsRead(pMain->pReal, aData, pMain->nPagesize, iOff);
   411    411           pMain->aCksum[ii] = genCksum(aData, pMain->nPagesize);
   412    412           if( ii+1==pMain->nPage && rc==SQLITE_IOERR_SHORT_READ ) rc = SQLITE_OK;
   413    413         }
   414    414       }
................................................................................
   462    462         */
   463    463         if( iSize>=(iOff+nSector) ){
   464    464           rc = sqlite3OsRead(pReal, zBuf, 28, iOff);
   465    465           if( rc!=SQLITE_OK || 0==decodeJournalHdr(zBuf, 0, 0, 0, 0) ){
   466    466             continue;
   467    467           }
   468    468         }
   469         -      nRec = (iSize-iOff) / (pMain->nPagesize+8);
          469  +      nRec = (u32)((iSize-iOff) / (pMain->nPagesize+8));
   470    470       }
   471    471   
   472    472       /* Read all the records that follow the journal-header just read. */
   473    473       for(ii=0; rc==SQLITE_OK && ii<nRec && iOff<iSize; ii++){
   474    474         u32 pgno;
   475    475         rc = sqlite3OsRead(pReal, zBuf, 4, iOff);
   476    476         if( rc==SQLITE_OK ){
................................................................................
   534    534       }
   535    535       if( p->iMaxOff<(iOfst + iAmt) ){
   536    536         p->iMaxOff = iOfst + iAmt;
   537    537       }
   538    538     }
   539    539   
   540    540     if( p->flags&SQLITE_OPEN_MAIN_DB && p->pWritable ){
   541         -    if( iAmt<p->nPagesize 
          541  +    if( iAmt<(int)p->nPagesize 
   542    542        && p->nPagesize%iAmt==0 
   543    543        && iOfst>=(PENDING_BYTE+512) 
   544    544        && iOfst+iAmt<=PENDING_BYTE+p->nPagesize
   545    545       ){
   546    546         /* No-op. This special case is hit when the backup code is copying a
   547    547         ** to a database with a larger page-size than the source database and
   548    548         ** it needs to fill in the non-locking-region part of the original
   549    549         ** pending-byte page.
   550    550         */
   551    551       }else{
   552         -      u32 pgno = iOfst/p->nPagesize + 1;
          552  +      u32 pgno = (u32)(iOfst/p->nPagesize + 1);
   553    553         assert( (iAmt==1||iAmt==p->nPagesize) && ((iOfst+iAmt)%p->nPagesize)==0 );
   554    554         assert( pgno<=p->nPage || p->nSync>0 );
   555    555         assert( pgno>p->nPage || sqlite3BitvecTest(p->pWritable, pgno) );
   556    556       }
   557    557     }
   558    558   
   559    559     rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
................................................................................
   574    574       /* Truncating a journal file. This is the end of a transaction. */
   575    575       jt_file *pMain = locateDatabaseHandle(p->zName);
   576    576       closeTransaction(pMain);
   577    577     }
   578    578     if( p->flags&SQLITE_OPEN_MAIN_DB && p->pWritable ){
   579    579       u32 pgno;
   580    580       u32 locking_page = (u32)(PENDING_BYTE/p->nPagesize+1);
   581         -    for(pgno=size/p->nPagesize+1; pgno<=p->nPage; pgno++){
          581  +    for(pgno=(u32)(size/p->nPagesize+1); pgno<=p->nPage; pgno++){
   582    582         assert( pgno==locking_page || sqlite3BitvecTest(p->pWritable, pgno) );
   583    583       }
   584    584     }
   585    585     return sqlite3OsTruncate(p->pReal, size);
   586    586   }
   587    587   
   588    588   /*

Changes to src/test_multiplex.c.

   325    325   
   326    326   #ifdef SQLITE_ENABLE_8_3_NAMES
   327    327     /* If JOURNAL_8_3_OFFSET is set to (say) 400, then any overflow files are 
   328    328     ** part of a database journal are named db.401, db.402, and so on. A 
   329    329     ** database may therefore not grow to larger than 400 chunks. Attempting
   330    330     ** to open chunk 401 indicates the database is full. */
   331    331     if( iChunk>=SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET ){
          332  +    sqlite3_log(SQLITE_FULL, "multiplexed chunk overflow: %s", pGroup->zName);
   332    333       *rc = SQLITE_FULL;
   333    334       return 0;
   334    335     }
   335    336   #endif
   336    337   
   337    338     *rc = multiplexSubFilename(pGroup, iChunk);
   338    339     if( (*rc)==SQLITE_OK && (pSubOpen = pGroup->aReal[iChunk].p)==0 ){
................................................................................
   343    344       }else if( iChunk==0 ){
   344    345         /* Fall through */
   345    346       }else if( pGroup->aReal[iChunk].z==0 ){
   346    347         return 0;
   347    348       }else{
   348    349         *rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[iChunk].z,
   349    350                                 SQLITE_ACCESS_EXISTS, &bExists);
   350         -      if( *rc || !bExists ) return 0;
          351  +     if( *rc || !bExists ){
          352  +        if( *rc ){
          353  +          sqlite3_log(*rc, "multiplexor.xAccess failure on %s",
          354  +                      pGroup->aReal[iChunk].z);
          355  +        }
          356  +        return 0;
          357  +      }
   351    358         flags &= ~SQLITE_OPEN_CREATE;
   352    359       }
   353    360       pSubOpen = sqlite3_malloc( pOrigVfs->szOsFile );
   354    361       if( pSubOpen==0 ){
   355    362         *rc = SQLITE_IOERR_NOMEM;
   356    363         return 0;
   357    364       }
   358    365       pGroup->aReal[iChunk].p = pSubOpen;
   359    366       *rc = pOrigVfs->xOpen(pOrigVfs, pGroup->aReal[iChunk].z, pSubOpen,
   360    367                             flags, pOutFlags);
   361    368       if( (*rc)!=SQLITE_OK ){
          369  +      sqlite3_log(*rc, "multiplexor.xOpen failure on %s",
          370  +                  pGroup->aReal[iChunk].z);
   362    371         sqlite3_free(pSubOpen);
   363    372         pGroup->aReal[iChunk].p = 0;
   364    373         return 0;
   365    374       }
   366    375     }
   367    376     return pSubOpen;
   368    377   }
................................................................................
   525    534       const char *zUri = (flags & SQLITE_OPEN_URI) ? zName : 0;
   526    535       /* assign pointers to extra space allocated */
   527    536       memset(pGroup, 0, sz);
   528    537       pMultiplexOpen->pGroup = pGroup;
   529    538       pGroup->bEnabled = -1;
   530    539       pGroup->bTruncate = sqlite3_uri_boolean(zUri, "truncate", 
   531    540                                      (flags & SQLITE_OPEN_MAIN_DB)==0);
   532         -    pGroup->szChunk = sqlite3_uri_int64(zUri, "chunksize",
          541  +    pGroup->szChunk = (int)sqlite3_uri_int64(zUri, "chunksize",
   533    542                                           SQLITE_MULTIPLEX_CHUNK_SIZE);
   534    543       pGroup->szChunk = (pGroup->szChunk+0xffff)&~0xffff;
   535    544       if( zName ){
   536    545         char *p = (char *)&pGroup[1];
   537    546         pGroup->zName = p;
   538    547         memcpy(pGroup->zName, zName, nName+1);
   539    548         pGroup->nName = nName;
................................................................................
   593    602             ** just disable the multiplexor all togethre.
   594    603             */
   595    604             rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z,
   596    605                 SQLITE_ACCESS_EXISTS, &bExists);
   597    606             bExists = multiplexSubSize(pGroup, 1, &rc)>0;
   598    607             if( rc==SQLITE_OK && bExists  && sz==(sz&0xffff0000) && sz>0
   599    608                 && sz!=pGroup->szChunk ){
   600         -            pGroup->szChunk = sz;
          609  +            pGroup->szChunk = (int)sz;
   601    610             }else if( rc==SQLITE_OK && !bExists && sz>pGroup->szChunk ){
   602    611               pGroup->bEnabled = 0;
   603    612             }
   604    613           }
   605    614         }
   606    615       }
   607    616   

Changes to src/test_onefile.c.

   284    284     sqlite3_file *pFile, 
   285    285     const void *zBuf, 
   286    286     int iAmt, 
   287    287     sqlite_int64 iOfst
   288    288   ){
   289    289     tmp_file *pTmp = (tmp_file *)pFile;
   290    290     if( (iAmt+iOfst)>pTmp->nAlloc ){
   291         -    int nNew = 2*(iAmt+iOfst+pTmp->nAlloc);
          291  +    int nNew = (int)(2*(iAmt+iOfst+pTmp->nAlloc));
   292    292       char *zNew = sqlite3_realloc(pTmp->zAlloc, nNew);
   293    293       if( !zNew ){
   294    294         return SQLITE_NOMEM;
   295    295       }
   296    296       pTmp->zAlloc = zNew;
   297    297       pTmp->nAlloc = nNew;
   298    298     }
   299    299     memcpy(&pTmp->zAlloc[iOfst], zBuf, iAmt);
   300         -  pTmp->nSize = MAX(pTmp->nSize, iOfst+iAmt);
          300  +  pTmp->nSize = (int)MAX(pTmp->nSize, iOfst+iAmt);
   301    301     return SQLITE_OK;
   302    302   }
   303    303   
   304    304   /*
   305    305   ** Truncate a tmp-file.
   306    306   */
   307    307   static int tmpTruncate(sqlite3_file *pFile, sqlite_int64 size){
   308    308     tmp_file *pTmp = (tmp_file *)pFile;
   309         -  pTmp->nSize = MIN(pTmp->nSize, size);
          309  +  pTmp->nSize = (int)MIN(pTmp->nSize, size);
   310    310     return SQLITE_OK;
   311    311   }
   312    312   
   313    313   /*
   314    314   ** Sync a tmp-file.
   315    315   */
   316    316   static int tmpSync(sqlite3_file *pFile, int flags){
................................................................................
   414    414       rc = SQLITE_IOERR_SHORT_READ;
   415    415     }else if( p->eType==DATABASE_FILE ){
   416    416       rc = pF->pMethods->xRead(pF, zBuf, iAmt, iOfst+BLOCKSIZE);
   417    417     }else{
   418    418       /* Journal file. */
   419    419       int iRem = iAmt;
   420    420       int iBuf = 0;
   421         -    int ii = iOfst;
          421  +    int ii = (int)iOfst;
   422    422       while( iRem>0 && rc==SQLITE_OK ){
   423    423         int iRealOff = pReal->nBlob - BLOCKSIZE*((ii/BLOCKSIZE)+1) + ii%BLOCKSIZE;
   424    424         int iRealAmt = MIN(iRem, BLOCKSIZE - (iRealOff%BLOCKSIZE));
   425    425   
   426    426         rc = pF->pMethods->xRead(pF, &((char *)zBuf)[iBuf], iRealAmt, iRealOff);
   427    427         ii += iRealAmt;
   428    428         iBuf += iRealAmt;
................................................................................
   449    449   
   450    450     if( p->eType==DATABASE_FILE ){
   451    451       if( (iAmt+iOfst+BLOCKSIZE)>(pReal->nBlob-pReal->nJournal) ){
   452    452         rc = SQLITE_FULL;
   453    453       }else{
   454    454         rc = pF->pMethods->xWrite(pF, zBuf, iAmt, iOfst+BLOCKSIZE);
   455    455         if( rc==SQLITE_OK ){
   456         -        pReal->nDatabase = MAX(pReal->nDatabase, iAmt+iOfst);
          456  +        pReal->nDatabase = (int)MAX(pReal->nDatabase, iAmt+iOfst);
   457    457         }
   458    458       }
   459    459     }else{
   460    460       /* Journal file. */
   461    461       int iRem = iAmt;
   462    462       int iBuf = 0;
   463         -    int ii = iOfst;
          463  +    int ii = (int)iOfst;
   464    464       while( iRem>0 && rc==SQLITE_OK ){
   465    465         int iRealOff = pReal->nBlob - BLOCKSIZE*((ii/BLOCKSIZE)+1) + ii%BLOCKSIZE;
   466    466         int iRealAmt = MIN(iRem, BLOCKSIZE - (iRealOff%BLOCKSIZE));
   467    467   
   468    468         if( iRealOff<(pReal->nDatabase+BLOCKSIZE) ){
   469    469           rc = SQLITE_FULL;
   470    470         }else{
................................................................................
   471    471           rc = pF->pMethods->xWrite(pF, &((char *)zBuf)[iBuf], iRealAmt,iRealOff);
   472    472           ii += iRealAmt;
   473    473           iBuf += iRealAmt;
   474    474           iRem -= iRealAmt;
   475    475         }
   476    476       }
   477    477       if( rc==SQLITE_OK ){
   478         -      pReal->nJournal = MAX(pReal->nJournal, iAmt+iOfst);
          478  +      pReal->nJournal = (int)MAX(pReal->nJournal, iAmt+iOfst);
   479    479       }
   480    480     }
   481    481   
   482    482     return rc;
   483    483   }
   484    484   
   485    485   /*
   486    486   ** Truncate an fs-file.
   487    487   */
   488    488   static int fsTruncate(sqlite3_file *pFile, sqlite_int64 size){
   489    489     fs_file *p = (fs_file *)pFile;
   490    490     fs_real_file *pReal = p->pReal;
   491    491     if( p->eType==DATABASE_FILE ){
   492         -    pReal->nDatabase = MIN(pReal->nDatabase, size);
          492  +    pReal->nDatabase = (int)MIN(pReal->nDatabase, size);
   493    493     }else{
   494         -    pReal->nJournal = MIN(pReal->nJournal, size);
          494  +    pReal->nJournal = (int)MIN(pReal->nJournal, size);
   495    495     }
   496    496     return SQLITE_OK;
   497    497   }
   498    498   
   499    499   /*
   500    500   ** Sync an fs-file.
   501    501   */
................................................................................
   637    637         goto open_out;
   638    638       }
   639    639       if( size==0 ){
   640    640         rc = pRealFile->pMethods->xWrite(pRealFile, "\0", 1, BLOBSIZE-1);
   641    641         pReal->nBlob = BLOBSIZE;
   642    642       }else{
   643    643         unsigned char zS[4];
   644         -      pReal->nBlob = size;
          644  +      pReal->nBlob = (int)size;
   645    645         rc = pRealFile->pMethods->xRead(pRealFile, zS, 4, 0);
   646    646         pReal->nDatabase = (zS[0]<<24)+(zS[1]<<16)+(zS[2]<<8)+zS[3];
   647    647         if( rc==SQLITE_OK ){
   648    648           rc = pRealFile->pMethods->xRead(pRealFile, zS, 4, pReal->nBlob-4);
   649    649           if( zS[0] || zS[1] || zS[2] || zS[3] ){
   650    650             pReal->nJournal = pReal->nBlob;
   651    651           }

Changes to src/test_osinst.c.

   238    238   }
   239    239   #else
   240    240   static sqlite3_uint64 vfslog_time(){
   241    241     return 0;
   242    242   }
   243    243   #endif
   244    244   
   245         -static void vfslog_call(sqlite3_vfs *, int, int, int, int, int, int);
          245  +static void vfslog_call(sqlite3_vfs *, int, int, sqlite3_int64, int, int, int);
   246    246   static void vfslog_string(sqlite3_vfs *, const char *);
   247    247   
   248    248   /*
   249    249   ** Close an vfslog-file.
   250    250   */
   251    251   static int vfslogClose(sqlite3_file *pFile){
   252    252     sqlite3_uint64 t;
................................................................................
   644    644     p[3] = v;
   645    645   }
   646    646   
   647    647   static void vfslog_call(
   648    648     sqlite3_vfs *pVfs,
   649    649     int eEvent,
   650    650     int iFileid,
   651         -  int nClick,
          651  +  sqlite3_int64 nClick,
   652    652     int return_code,
   653    653     int size,
   654    654     int offset
   655    655   ){
   656    656     VfslogVfs *p = (VfslogVfs *)pVfs;
   657    657     unsigned char *zRec;
   658    658     if( (24+p->nBuf)>sizeof(p->aBuf) ){
   659    659       vfslog_flush(p);
   660    660     }
   661    661     zRec = (unsigned char *)&p->aBuf[p->nBuf];
   662    662     put32bits(&zRec[0], eEvent);
   663    663     put32bits(&zRec[4], iFileid);
   664         -  put32bits(&zRec[8], nClick);
          664  +  put32bits(&zRec[8], (unsigned int)(nClick&0xffff));
   665    665     put32bits(&zRec[12], return_code);
   666    666     put32bits(&zRec[16], size);
   667    667     put32bits(&zRec[20], offset);
   668    668     p->nBuf += 24;
   669    669   }
   670    670   
   671    671   static void vfslog_string(sqlite3_vfs *pVfs, const char *zStr){
................................................................................
  1039   1039     switch( i ){
  1040   1040       case 0: {
  1041   1041         sqlite3_result_text(ctx, vfslog_eventname(val), -1, SQLITE_STATIC);
  1042   1042         break;
  1043   1043       }
  1044   1044       case 1: {
  1045   1045         char *zStr = pCsr->zTransient;
  1046         -      if( val!=0 && val<pCsr->nFile ){
         1046  +      if( val!=0 && val<(unsigned)pCsr->nFile ){
  1047   1047           zStr = pCsr->azFile[val];
  1048   1048         }
  1049   1049         sqlite3_result_text(ctx, zStr, -1, SQLITE_TRANSIENT);
  1050   1050         break;
  1051   1051       }
  1052   1052       default:
  1053   1053         sqlite3_result_int(ctx, val);

Changes to src/test_quota.c.

   116    116   ** open file.  This object is opaque to all users - the internal
   117    117   ** structure is only visible to the functions below.
   118    118   */
   119    119   struct quota_FILE {
   120    120     FILE *f;                /* Open stdio file pointer */
   121    121     sqlite3_int64 iOfst;    /* Current offset into the file */
   122    122     quotaFile *pFile;       /* The file record in the quota system */
          123  +#if SQLITE_OS_WIN
          124  +  char *zMbcsName;        /* Full MBCS pathname of the file */
          125  +#endif
   123    126   };
   124    127   
   125    128   
   126    129   /************************* Global Variables **********************************/
   127    130   /*
   128    131   ** All global variables used by this file are containing within the following
   129    132   ** gQuota structure.
................................................................................
   975    978   
   976    979   /*
   977    980   ** Open a potentially quotaed file for I/O.
   978    981   */
   979    982   quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode){
   980    983     quota_FILE *p = 0;
   981    984     char *zFull = 0;
   982         -  char *zFullTranslated;
          985  +  char *zFullTranslated = 0;
   983    986     int rc;
   984    987     quotaGroup *pGroup;
   985    988     quotaFile *pFile;
   986    989   
   987    990     zFull = (char*)sqlite3_malloc(gQuota.sThisVfs.mxPathname + 1);
   988    991     if( zFull==0 ) return 0;
   989    992     rc = gQuota.pOrigVfs->xFullPathname(gQuota.pOrigVfs, zFilename,
................................................................................
   991    994     if( rc ) goto quota_fopen_error;
   992    995     p = (quota_FILE*)sqlite3_malloc(sizeof(*p));
   993    996     if( p==0 ) goto quota_fopen_error;
   994    997     memset(p, 0, sizeof(*p));
   995    998     zFullTranslated = quota_utf8_to_mbcs(zFull);
   996    999     if( zFullTranslated==0 ) goto quota_fopen_error;
   997   1000     p->f = fopen(zFullTranslated, zMode);
   998         -  quota_mbcs_free(zFullTranslated);
   999   1001     if( p->f==0 ) goto quota_fopen_error;
  1000   1002     quotaEnter();
  1001   1003     pGroup = quotaGroupFind(zFull);
  1002   1004     if( pGroup ){
  1003   1005       pFile = quotaFindFile(pGroup, zFull, 1);
  1004   1006       if( pFile==0 ){
  1005   1007         quotaLeave();
................................................................................
  1006   1008         goto quota_fopen_error;
  1007   1009       }
  1008   1010       pFile->nRef++;
  1009   1011       p->pFile = pFile;
  1010   1012     }
  1011   1013     quotaLeave();
  1012   1014     sqlite3_free(zFull);
         1015  +#if SQLITE_OS_WIN
         1016  +  p->zMbcsName = zFullTranslated;
         1017  +#endif
  1013   1018     return p;
  1014   1019   
  1015   1020   quota_fopen_error:
         1021  +  quota_mbcs_free(zFullTranslated);
  1016   1022     sqlite3_free(zFull);
  1017   1023     if( p && p->f ) fclose(p->f);
  1018   1024     sqlite3_free(p);
  1019   1025     return 0;
  1020   1026   }
  1021   1027   
  1022   1028   /*
................................................................................
  1041   1047     size_t nmemb,          /* Number of elements */
  1042   1048     quota_FILE *p          /* Write to this quota_FILE objecct */
  1043   1049   ){
  1044   1050     sqlite3_int64 iOfst;
  1045   1051     sqlite3_int64 iEnd;
  1046   1052     sqlite3_int64 szNew;
  1047   1053     quotaFile *pFile;
         1054  +  size_t rc;
  1048   1055     
  1049   1056     iOfst = ftell(p->f);
  1050   1057     iEnd = iOfst + size*nmemb;
  1051   1058     pFile = p->pFile;
  1052   1059     if( pFile && pFile->iSize<iEnd ){
  1053   1060       quotaGroup *pGroup = pFile->pGroup;
  1054   1061       quotaEnter();
................................................................................
  1056   1063       if( szNew>pGroup->iLimit && pGroup->iLimit>0 ){
  1057   1064         if( pGroup->xCallback ){
  1058   1065           pGroup->xCallback(pFile->zFilename, &pGroup->iLimit, szNew, 
  1059   1066                             pGroup->pArg);
  1060   1067         }
  1061   1068         if( szNew>pGroup->iLimit && pGroup->iLimit>0 ){
  1062   1069           iEnd = pGroup->iLimit - pGroup->iSize + pFile->iSize;
  1063         -        nmemb = (iEnd - iOfst)/size;
         1070  +        nmemb = (size_t)((iEnd - iOfst)/size);
  1064   1071           iEnd = iOfst + size*nmemb;
  1065   1072           szNew = pGroup->iSize - pFile->iSize + iEnd;
  1066   1073         }
  1067   1074       }
  1068   1075       pGroup->iSize = szNew;
  1069   1076       pFile->iSize = iEnd;
  1070   1077       quotaLeave();
         1078  +  }else{
         1079  +    pFile = 0;
  1071   1080     }
  1072         -  return fwrite(pBuf, size, nmemb, p->f);
         1081  +  rc = fwrite(pBuf, size, nmemb, p->f);
         1082  +
         1083  +  /* If the write was incomplete, adjust the file size and group size
         1084  +  ** downward */
         1085  +  if( rc<nmemb && pFile ){
         1086  +    size_t nWritten = rc>=0 ? rc : 0;
         1087  +    sqlite3_int64 iNewEnd = iOfst + size*nWritten;
         1088  +    if( iNewEnd<iEnd ) iNewEnd = iEnd;
         1089  +    quotaEnter();
         1090  +    pFile->pGroup->iSize += iNewEnd - pFile->iSize;
         1091  +    pFile->iSize = iNewEnd;
         1092  +    quotaLeave();
         1093  +  }
         1094  +  return rc;    
  1073   1095   }
  1074   1096   
  1075   1097   /*
  1076   1098   ** Close an open quota_FILE stream.
  1077   1099   */
  1078   1100   int sqlite3_quota_fclose(quota_FILE *p){
  1079   1101     int rc;
................................................................................
  1089   1111           gQuota.pOrigVfs->xDelete(gQuota.pOrigVfs, pFile->zFilename, 0);
  1090   1112           quotaRemoveFile(pFile);
  1091   1113         }
  1092   1114         quotaGroupDeref(pGroup);
  1093   1115       }
  1094   1116       quotaLeave();
  1095   1117     }
         1118  +#if SQLITE_OS_WIN
         1119  +  quota_mbcs_free(p->zMbcsName);
         1120  +#endif
  1096   1121     sqlite3_free(p);
  1097   1122     return rc;
  1098   1123   }
  1099   1124   
  1100   1125   /*
  1101   1126   ** Flush memory buffers for a quota_FILE to disk.
  1102   1127   */
................................................................................
  1130   1155   
  1131   1156   /*
  1132   1157   ** Tell the current location of a quota_FILE stream.
  1133   1158   */
  1134   1159   long sqlite3_quota_ftell(quota_FILE *p){
  1135   1160     return ftell(p->f);
  1136   1161   }
         1162  +
         1163  +/*
         1164  +** Truncate a file to szNew bytes.
         1165  +*/
         1166  +int sqlite3_quota_ftruncate(quota_FILE *p, sqlite3_int64 szNew){
         1167  +  quotaFile *pFile = p->pFile;
         1168  +  int rc;
         1169  +  if( (pFile = p->pFile)!=0 && pFile->iSize<szNew ){
         1170  +    quotaGroup *pGroup;
         1171  +    if( pFile->iSize<szNew ){
         1172  +      /* This routine cannot be used to extend a file that is under
         1173  +      ** quota management.  Only true truncation is allowed. */
         1174  +      return -1;
         1175  +    }
         1176  +    pGroup = pFile->pGroup;
         1177  +    quotaEnter();
         1178  +    pGroup->iSize += szNew - pFile->iSize;
         1179  +    quotaLeave();
         1180  +  }
         1181  +#if SQLITE_OS_UNIX
         1182  +  rc = ftruncate(fileno(p->f), szNew);
         1183  +#endif
         1184  +#if SQLITE_OS_WIN
         1185  +  rc = _chsize_s(_fileno(p->f), szNew);
         1186  +#endif
         1187  +  if( pFile && rc==0 ){
         1188  +    quotaGroup *pGroup = pFile->pGroup;
         1189  +    quotaEnter();
         1190  +    pGroup->iSize += szNew - pFile->iSize;
         1191  +    pFile->iSize = szNew;
         1192  +    quotaLeave();
         1193  +  }
         1194  +  return rc;
         1195  +}
         1196  +
         1197  +/*
         1198  +** Determine the time that the given file was last modified, in
         1199  +** seconds size 1970.  Write the result into *pTime.  Return 0 on
         1200  +** success and non-zero on any kind of error.
         1201  +*/
         1202  +int sqlite3_quota_file_mtime(quota_FILE *p, time_t *pTime){
         1203  +  int rc;
         1204  +#if SQLITE_OS_UNIX
         1205  +  struct stat buf;
         1206  +  rc = fstat(fileno(p->f), &buf);
         1207  +#endif
         1208  +#if SQLITE_OS_WIN
         1209  +  struct _stati64 buf;
         1210  +  rc = _stati64(p->zMbcsName, &buf);
         1211  +#endif
         1212  +  if( rc==0 ) *pTime = buf.st_mtime;
         1213  +  return rc;
         1214  +}
         1215  +
         1216  +/*
         1217  +** Return the true size of the file, as reported by the operating
         1218  +** system.
         1219  +*/
         1220  +sqlite3_int64 sqlite3_quota_file_truesize(quota_FILE *p){
         1221  +  int rc;
         1222  +#if SQLITE_OS_UNIX
         1223  +  struct stat buf;
         1224  +  rc = fstat(fileno(p->f), &buf);
         1225  +#endif
         1226  +#if SQLITE_OS_WIN
         1227  +  struct _stati64 buf;
         1228  +  rc = _stati64(p->zMbcsName, &buf);
         1229  +#endif
         1230  +  return rc==0 ? buf.st_size : -1;
         1231  +}
         1232  +
         1233  +/*
         1234  +** Return the size of the file, as it is known to the quota subsystem.
         1235  +*/
         1236  +sqlite3_int64 sqlite3_quota_file_size(quota_FILE *p){
         1237  +  return p->pFile ? p->pFile->iSize : -1;
         1238  +}
  1137   1239   
  1138   1240   /*
  1139   1241   ** Remove a managed file.  Update quotas accordingly.
  1140   1242   */
  1141   1243   int sqlite3_quota_remove(const char *zFilename){
  1142   1244     char *zFull;            /* Full pathname for zFilename */
  1143   1245     int nFull;              /* Number of bytes in zFilename */
................................................................................
  1651   1753       return TCL_ERROR;
  1652   1754     }
  1653   1755     p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
  1654   1756     x = sqlite3_quota_ftell(p);
  1655   1757     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
  1656   1758     return TCL_OK;
  1657   1759   }
         1760  +
         1761  +/*
         1762  +** tclcmd: sqlite3_quota_ftruncate HANDLE SIZE
         1763  +*/
         1764  +static int test_quota_ftruncate(
         1765  +  void * clientData,
         1766  +  Tcl_Interp *interp,
         1767  +  int objc,
         1768  +  Tcl_Obj *CONST objv[]
         1769  +){
         1770  +  quota_FILE *p;
         1771  +  sqlite3_int64 x;
         1772  +  Tcl_WideInt w;
         1773  +  int rc;
         1774  +  if( objc!=3 ){
         1775  +    Tcl_WrongNumArgs(interp, 1, objv, "HANDLE SIZE");
         1776  +    return TCL_ERROR;
         1777  +  }
         1778  +  p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
         1779  +  if( Tcl_GetWideIntFromObj(interp, objv[2], &w) ) return TCL_ERROR;
         1780  +  x = (sqlite3_int64)w;
         1781  +  rc = sqlite3_quota_ftruncate(p, x);
         1782  +  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
         1783  +  return TCL_OK;
         1784  +}
         1785  +
         1786  +/*
         1787  +** tclcmd: sqlite3_quota_file_size HANDLE
         1788  +*/
         1789  +static int test_quota_file_size(
         1790  +  void * clientData,
         1791  +  Tcl_Interp *interp,
         1792  +  int objc,
         1793  +  Tcl_Obj *CONST objv[]
         1794  +){
         1795  +  quota_FILE *p;
         1796  +  sqlite3_int64 x;
         1797  +  if( objc!=2 ){
         1798  +    Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
         1799  +    return TCL_ERROR;
         1800  +  }
         1801  +  p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
         1802  +  x = sqlite3_quota_file_size(p);
         1803  +  Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
         1804  +  return TCL_OK;
         1805  +}
         1806  +
         1807  +/*
         1808  +** tclcmd: sqlite3_quota_file_truesize HANDLE
         1809  +*/
         1810  +static int test_quota_file_truesize(
         1811  +  void * clientData,
         1812  +  Tcl_Interp *interp,
         1813  +  int objc,
         1814  +  Tcl_Obj *CONST objv[]
         1815  +){
         1816  +  quota_FILE *p;
         1817  +  sqlite3_int64 x;
         1818  +  if( objc!=2 ){
         1819  +    Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
         1820  +    return TCL_ERROR;
         1821  +  }
         1822  +  p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
         1823  +  x = sqlite3_quota_file_truesize(p);
         1824  +  Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
         1825  +  return TCL_OK;
         1826  +}
         1827  +
         1828  +/*
         1829  +** tclcmd: sqlite3_quota_file_mtime HANDLE
         1830  +*/
         1831  +static int test_quota_file_mtime(
         1832  +  void * clientData,
         1833  +  Tcl_Interp *interp,
         1834  +  int objc,
         1835  +  Tcl_Obj *CONST objv[]
         1836  +){
         1837  +  quota_FILE *p;
         1838  +  time_t t;
         1839  +  if( objc!=2 ){
         1840  +    Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
         1841  +    return TCL_ERROR;
         1842  +  }
         1843  +  p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
         1844  +  t = 0;
         1845  +  sqlite3_quota_file_mtime(p, &t);
         1846  +  Tcl_SetObjResult(interp, Tcl_NewWideIntObj(t));
         1847  +  return TCL_OK;
         1848  +}
         1849  +
  1658   1850   
  1659   1851   /*
  1660   1852   ** tclcmd: sqlite3_quota_remove FILENAME
  1661   1853   */
  1662   1854   static int test_quota_remove(
  1663   1855     void * clientData,
  1664   1856     Tcl_Interp *interp,
................................................................................
  1709   1901   ** of this module.
  1710   1902   */
  1711   1903   int Sqlitequota_Init(Tcl_Interp *interp){
  1712   1904     static struct {
  1713   1905        char *zName;
  1714   1906        Tcl_ObjCmdProc *xProc;
  1715   1907     } aCmd[] = {
  1716         -    { "sqlite3_quota_initialize", test_quota_initialize },
  1717         -    { "sqlite3_quota_shutdown",   test_quota_shutdown },
  1718         -    { "sqlite3_quota_set",        test_quota_set },
  1719         -    { "sqlite3_quota_file",       test_quota_file },
  1720         -    { "sqlite3_quota_dump",       test_quota_dump },
  1721         -    { "sqlite3_quota_fopen",      test_quota_fopen },
  1722         -    { "sqlite3_quota_fread",      test_quota_fread },
  1723         -    { "sqlite3_quota_fwrite",     test_quota_fwrite },
  1724         -    { "sqlite3_quota_fclose",     test_quota_fclose },
  1725         -    { "sqlite3_quota_fflush",     test_quota_fflush },
  1726         -    { "sqlite3_quota_fseek",      test_quota_fseek },
  1727         -    { "sqlite3_quota_rewind",     test_quota_rewind },
  1728         -    { "sqlite3_quota_ftell",      test_quota_ftell },
  1729         -    { "sqlite3_quota_remove",     test_quota_remove },
  1730         -    { "sqlite3_quota_glob",       test_quota_glob },
         1908  +    { "sqlite3_quota_initialize",    test_quota_initialize },
         1909  +    { "sqlite3_quota_shutdown",      test_quota_shutdown },
         1910  +    { "sqlite3_quota_set",           test_quota_set },
         1911  +    { "sqlite3_quota_file",          test_quota_file },
         1912  +    { "sqlite3_quota_dump",          test_quota_dump },
         1913  +    { "sqlite3_quota_fopen",         test_quota_fopen },
         1914  +    { "sqlite3_quota_fread",         test_quota_fread },
         1915  +    { "sqlite3_quota_fwrite",        test_quota_fwrite },
         1916  +    { "sqlite3_quota_fclose",        test_quota_fclose },
         1917  +    { "sqlite3_quota_fflush",        test_quota_fflush },
         1918  +    { "sqlite3_quota_fseek",         test_quota_fseek },
         1919  +    { "sqlite3_quota_rewind",        test_quota_rewind },
         1920  +    { "sqlite3_quota_ftell",         test_quota_ftell },
         1921  +    { "sqlite3_quota_ftruncate",     test_quota_ftruncate },
         1922  +    { "sqlite3_quota_file_size",     test_quota_file_size },
         1923  +    { "sqlite3_quota_file_truesize", test_quota_file_truesize },
         1924  +    { "sqlite3_quota_file_mtime",    test_quota_file_mtime },
         1925  +    { "sqlite3_quota_remove",        test_quota_remove },
         1926  +    { "sqlite3_quota_glob",          test_quota_glob },
  1731   1927     };
  1732   1928     int i;
  1733   1929   
  1734   1930     for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
  1735   1931       Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  1736   1932     }
  1737   1933   
  1738   1934     return TCL_OK;
  1739   1935   }
  1740   1936   #endif

Changes to src/test_quota.h.

    25     25   ** callback does enlarge the quota such that the total size of all
    26     26   ** files within the group is less than the new quota, then the write
    27     27   ** continues as if nothing had happened.
    28     28   */
    29     29   #ifndef _QUOTA_H_
    30     30   #include "sqlite3.h"
    31     31   #include <stdio.h>
           32  +#include <sys/types.h>
           33  +#include <sys/stat.h>
           34  +#if SQLITE_OS_UNIX
           35  +# include <unistd.h>
           36  +#endif
           37  +#if SQLITE_OS_WIN
           38  +# include <windows.h>
           39  +#endif
    32     40   
    33     41   /* Make this callable from C++ */
    34     42   #ifdef __cplusplus
    35     43   extern "C" {
    36     44   #endif
    37     45   
    38     46   /*
................................................................................
   178    186   ** Move the read/write pointer for a quota_FILE object.  Or tell the
   179    187   ** current location of the read/write pointer.
   180    188   */
   181    189   int sqlite3_quota_fseek(quota_FILE*, long, int);
   182    190   void sqlite3_quota_rewind(quota_FILE*);
   183    191   long sqlite3_quota_ftell(quota_FILE*);
   184    192   
          193  +/*
          194  +** Truncate a file previously opened by sqlite3_quota_fopen().  Return
          195  +** zero on success and non-zero on any kind of failure.
          196  +**
          197  +** The newSize argument must be less than or equal to the current file size.
          198  +** Any attempt to "truncate" a file to a larger size results in 
          199  +** undefined behavior.
          200  +*/
          201  +int sqlite3_quota_ftrunate(quota_FILE*, sqlite3_int64 newSize);
          202  +
          203  +/*
          204  +** Return the last modification time of the opened file, in seconds
          205  +** since 1970.
          206  +*/
          207  +int sqlite3_quota_file_mtime(quota_FILE*, time_t *pTime);
          208  +
          209  +/*
          210  +** Return the size of the file as it is known to the quota system.
          211  +**
          212  +** This size might be different from the true size of the file on
          213  +** disk if some outside process has modified the file without using the
          214  +** quota mechanism, or if calls to sqlite3_quota_fwrite() have occurred
          215  +** which have increased the file size, but those writes have not yet been
          216  +** forced to disk using sqlite3_quota_fflush().
          217  +**
          218  +** Return -1 if the file is not participating in quota management.
          219  +*/
          220  +sqlite3_int64 sqlite3_quota_file_size(quota_FILE*);
          221  +
          222  +/*
          223  +** Return the true size of the file.
          224  +**
          225  +** The true size should be the same as the size of the file as known
          226  +** to the quota system, however the sizes might be different if the
          227  +** file has been extended or truncated via some outside process or if
          228  +** pending writes have not yet been flushed to disk.
          229  +**
          230  +** Return -1 if the file does not exist or if the size of the file
          231  +** cannot be determined for some reason.
          232  +*/
          233  +sqlite3_int64 sqlite3_quota_file_truesize(quota_FILE*);
          234  +
   185    235   /*
   186    236   ** Delete a file from the disk, if that file is under quota management.
   187    237   ** Adjust quotas accordingly.
   188    238   **
   189    239   ** If zFilename is the name of a directory that matches one of the
   190    240   ** quota glob patterns, then all files under quota management that
   191    241   ** are contained within that directory are deleted.

Changes to src/test_rtree.c.

    45     45   
    46     46   /*
    47     47   ** Implementation of "circle" r-tree geometry callback.
    48     48   */
    49     49   static int circle_geom(
    50     50     sqlite3_rtree_geometry *p,
    51     51     int nCoord, 
           52  +#ifdef SQLITE_RTREE_INT_ONLY
           53  +  sqlite3_int64 *aCoord,
           54  +#else
    52     55     double *aCoord, 
           56  +#endif
    53     57     int *pRes
    54     58   ){
    55     59     int i;                          /* Iterator variable */
    56     60     Circle *pCircle;                /* Structure defining circular region */
    57     61     double xmin, xmax;              /* X dimensions of box being tested */
    58     62     double ymin, ymax;              /* X dimensions of box being tested */
    59     63   
................................................................................
   184    188   **
   185    189   **   cube(x, y, z, width, height, depth)
   186    190   **
   187    191   ** The width, height and depth parameters must all be greater than zero.
   188    192   */
   189    193   static int cube_geom(
   190    194     sqlite3_rtree_geometry *p,
   191         -  int nCoord, 
          195  +  int nCoord,
          196  +#ifdef SQLITE_RTREE_INT_ONLY
          197  +  sqlite3_int64 *aCoord, 
          198  +#else
   192    199     double *aCoord, 
          200  +#endif
   193    201     int *piRes
   194    202   ){
   195    203     Cube *pCube = (Cube *)p->pUser;
   196    204   
   197    205     assert( p->pContext==(void *)&gHere );
   198    206   
   199    207     if( pCube==0 ){

Changes to src/test_stat.c.

   320    320           u32 nPayload;             /* Bytes of payload total (local+overflow) */
   321    321           int nLocal;               /* Bytes of payload stored locally */
   322    322           iOff += getVarint32(&aData[iOff], nPayload);
   323    323           if( p->flags==0x0D ){
   324    324             u64 dummy;
   325    325             iOff += sqlite3GetVarint(&aData[iOff], &dummy);
   326    326           }
   327         -        if( nPayload>p->nMxPayload ) p->nMxPayload = nPayload;
          327  +        if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
   328    328           getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
   329    329           pCell->nLocal = nLocal;
          330  +        assert( nLocal>=0 );
   330    331           assert( nPayload>=nLocal );
   331    332           assert( nLocal<=(nUsable-35) );
   332         -        if( nPayload>nLocal ){
          333  +        if( nPayload>(u32)nLocal ){
   333    334             int j;
   334    335             int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
   335    336             pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
   336    337             pCell->nOvfl = nOvfl;
   337    338             pCell->aOvfl = sqlite3_malloc(sizeof(u32)*nOvfl);
   338    339             pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
   339    340             for(j=1; j<nOvfl; j++){
................................................................................
   374    375     /* If connected to a ZIPVFS backend, override the page size and
   375    376     ** offset with actual values obtained from ZIPVFS.
   376    377     */
   377    378     fd = sqlite3PagerFile(pPager);
   378    379     x[0] = pCsr->iPageno;
   379    380     if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
   380    381       pCsr->iOffset = x[0];
   381         -    pCsr->szPage = x[1];
          382  +    pCsr->szPage = (int)x[1];
   382    383     }
   383    384   }
   384    385   
   385    386   /*
   386    387   ** Move a statvfs cursor to the next entry in the file.
   387    388   */
   388    389   static int statNext(sqlite3_vtab_cursor *pCursor){
................................................................................
   396    397     sqlite3_free(pCsr->zPath);
   397    398     pCsr->zPath = 0;
   398    399   
   399    400     if( pCsr->aPage[0].pPg==0 ){
   400    401       rc = sqlite3_step(pCsr->pStmt);
   401    402       if( rc==SQLITE_ROW ){
   402    403         int nPage;
   403         -      u32 iRoot = sqlite3_column_int64(pCsr->pStmt, 1);
          404  +      u32 iRoot = (u32)sqlite3_column_int64(pCsr->pStmt, 1);
   404    405         sqlite3PagerPagecount(pPager, &nPage);
   405    406         if( nPage==0 ){
   406    407           pCsr->isEof = 1;
   407    408           return sqlite3_reset(pCsr->pStmt);
   408    409         }
   409    410         rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg);
   410    411         pCsr->aPage[0].iPgno = iRoot;

Changes to src/test_wholenumber.c.

    29     29   #ifndef SQLITE_OMIT_VIRTUALTABLE
    30     30   
    31     31   
    32     32   /* A wholenumber cursor object */
    33     33   typedef struct wholenumber_cursor wholenumber_cursor;
    34     34   struct wholenumber_cursor {
    35     35     sqlite3_vtab_cursor base;  /* Base class - must be first */
    36         -  unsigned iValue;           /* Current value */
    37         -  unsigned mxValue;          /* Maximum value */
           36  +  sqlite3_int64 iValue;      /* Current value */
           37  +  sqlite3_int64 mxValue;     /* Maximum value */
    38     38   };
    39     39   
    40     40   /* Methods for the wholenumber module */
    41     41   static int wholenumberConnect(
    42     42     sqlite3 *db,
    43     43     void *pAux,
    44     44     int argc, const char *const*argv,

Changes to src/vdbe.c.

  2730   2730             p->rc = rc = SQLITE_BUSY;
  2731   2731             goto vdbe_return;
  2732   2732           }
  2733   2733           db->isTransactionSavepoint = 0;
  2734   2734           rc = p->rc;
  2735   2735         }else{
  2736   2736           iSavepoint = db->nSavepoint - iSavepoint - 1;
  2737         -        for(ii=0; ii<db->nDb; ii++){
  2738         -          sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, SQLITE_ABORT);
         2737  +        if( p1==SAVEPOINT_ROLLBACK ){
         2738  +          for(ii=0; ii<db->nDb; ii++){
         2739  +            sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, SQLITE_ABORT);
         2740  +          }
  2739   2741           }
  2740   2742           for(ii=0; ii<db->nDb; ii++){
  2741   2743             rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
  2742   2744             if( rc!=SQLITE_OK ){
  2743   2745               goto abort_due_to_error;
  2744   2746             }
  2745   2747           }

Changes to src/vdbeaux.c.

  1235   1235         */
  1236   1236         if( pOp->p4type==P4_SUBPROGRAM ){
  1237   1237           int nByte = (nSub+1)*sizeof(SubProgram*);
  1238   1238           int j;
  1239   1239           for(j=0; j<nSub; j++){
  1240   1240             if( apSub[j]==pOp->p4.pProgram ) break;
  1241   1241           }
  1242         -        if( j==nSub && SQLITE_OK==sqlite3VdbeMemGrow(pSub, nByte, 1) ){
         1242  +        if( j==nSub && SQLITE_OK==sqlite3VdbeMemGrow(pSub, nByte, nSub!=0) ){
  1243   1243             apSub = (SubProgram **)pSub->z;
  1244   1244             apSub[nSub++] = pOp->p4.pProgram;
  1245   1245             pSub->flags |= MEM_Blob;
  1246   1246             pSub->n = nSub*sizeof(SubProgram*);
  1247   1247           }
  1248   1248         }
  1249   1249       }

Changes to src/vdbemem.c.

    55     55   #endif
    56     56   }
    57     57   
    58     58   /*
    59     59   ** Make sure pMem->z points to a writable allocation of at least 
    60     60   ** n bytes.
    61     61   **
    62         -** If the memory cell currently contains string or blob data
    63         -** and the third argument passed to this function is true, the 
    64         -** current content of the cell is preserved. Otherwise, it may
    65         -** be discarded.  
           62  +** If the third argument passed to this function is true, then memory
           63  +** cell pMem must contain a string or blob. In this case the content is
           64  +** preserved. Otherwise, if the third parameter to this function is false,
           65  +** any current string or blob value may be discarded.
    66     66   **
    67     67   ** This function sets the MEM_Dyn flag and clears any xDel callback.
    68     68   ** It also clears MEM_Ephem and MEM_Static. If the preserve flag is 
    69     69   ** not set, Mem.n is zeroed.
    70     70   */
    71     71   int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){
    72     72     assert( 1 >=
    73     73       ((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) +
    74     74       (((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) + 
    75     75       ((pMem->flags&MEM_Ephem) ? 1 : 0) + 
    76     76       ((pMem->flags&MEM_Static) ? 1 : 0)
    77     77     );
    78     78     assert( (pMem->flags&MEM_RowSet)==0 );
           79  +
           80  +  /* If the preserve flag is set to true, then the memory cell must already
           81  +  ** contain a valid string or blob value.  */
           82  +  assert( preserve==0 || pMem->flags&(MEM_Blob|MEM_Str) );
    79     83   
    80     84     if( n<32 ) n = 32;
    81     85     if( sqlite3DbMallocSize(pMem->db, pMem->zMalloc)<n ){
    82     86       if( preserve && pMem->z==pMem->zMalloc ){
    83     87         pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
    84     88         preserve = 0;
    85     89       }else{

Changes to test/capi3.test.

   897    897   } {0 {}}
   898    898   do_test capi3-11.9.3 {
   899    899     sqlite3_get_autocommit $DB
   900    900   } 1
   901    901   do_test capi3-11.10 {
   902    902     sqlite3_step $STMT
   903    903   } {SQLITE_ERROR}
          904  +ifcapable !autoreset {
          905  +  # If SQLITE_OMIT_AUTORESET is defined, then the statement must be
          906  +  # reset() before it can be passed to step() again.
          907  +  do_test capi3-11.11a { sqlite3_step $STMT } {SQLITE_MISUSE}
          908  +  do_test capi3-11.11b { sqlite3_reset $STMT } {SQLITE_ABORT}
          909  +}
   904    910   do_test capi3-11.11 {
   905    911     sqlite3_step $STMT
   906    912   } {SQLITE_ROW}
   907    913   do_test capi3-11.12 {
   908    914     sqlite3_step $STMT
   909    915     sqlite3_step $STMT
   910    916   } {SQLITE_DONE}

Changes to test/capi3c.test.

   852    852   } {0 {}}
   853    853   do_test capi3c-11.9.3 {
   854    854     sqlite3_get_autocommit $DB
   855    855   } 1
   856    856   do_test capi3c-11.10 {
   857    857     sqlite3_step $STMT
   858    858   } {SQLITE_ABORT}
          859  +ifcapable !autoreset {
          860  +  # If SQLITE_OMIT_AUTORESET is defined, then the statement must be
          861  +  # reset() before it can be passed to step() again.
          862  +  do_test capi3-11.11a { sqlite3_step $STMT } {SQLITE_MISUSE}
          863  +  do_test capi3-11.11b { sqlite3_reset $STMT } {SQLITE_ABORT}
          864  +}
   859    865   do_test capi3c-11.11 {
   860    866     sqlite3_step $STMT
   861    867   } {SQLITE_ROW}
   862    868   do_test capi3c-11.12 {
   863    869     sqlite3_step $STMT
   864    870     sqlite3_step $STMT
   865    871   } {SQLITE_DONE}

Changes to test/check.test.

   113    113       SELECT * FROM t1;
   114    114     }
   115    115   } {4 11.0}
   116    116   
   117    117   do_test check-2.1 {
   118    118     execsql {
   119    119       CREATE TABLE t2(
   120         -      x INTEGER CHECK( typeof(coalesce(x,0))=="integer" ),
   121         -      y REAL CHECK( typeof(coalesce(y,0.1))=='real' ),
   122         -      z TEXT CHECK( typeof(coalesce(z,''))=='text' )
          120  +      x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=="integer" ),
          121  +      y REAL CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ),
          122  +      z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' )
   123    123       );
   124    124     }
   125    125   } {}
   126    126   do_test check-2.2 {
   127    127     execsql {
   128    128       INSERT INTO t2 VALUES(1,2.2,'three');
   129    129       SELECT * FROM t2;
................................................................................
   137    137       SELECT * FROM t2;
   138    138     }
   139    139   } {1 2.2 three {} {} {}}
   140    140   do_test check-2.4 {
   141    141     catchsql {
   142    142       INSERT INTO t2 VALUES(1.1, NULL, NULL);
   143    143     }
   144         -} {1 {constraint failed}}
          144  +} {1 {constraint one failed}}
   145    145   do_test check-2.5 {
   146    146     catchsql {
   147    147       INSERT INTO t2 VALUES(NULL, 5, NULL);
   148    148     }
   149         -} {1 {constraint failed}}
          149  +} {1 {constraint two failed}}
   150    150   do_test check-2.6 {
   151    151     catchsql {
   152    152       INSERT INTO t2 VALUES(NULL, NULL, 3.14159);
   153    153     }
   154         -} {1 {constraint failed}}
          154  +} {1 {constraint three failed}}
   155    155   
   156    156   ifcapable subquery {
   157    157     do_test check-3.1 {
   158    158       catchsql {
   159    159         CREATE TABLE t3(
   160    160           x, y, z,
   161    161           CHECK( x<(SELECT min(x) FROM t1) )

Changes to test/fts3defer.test.

   485    485     INSERT INTO x2 VALUES('a b c d e f g h i j k l m n o p q r s t u v w x y m');
   486    486     COMMIT;
   487    487   }
   488    488   do_execsql_test 4.2 {
   489    489     SELECT * FROM x2 WHERE x2 MATCH 'a b c d e f g h i j k l m n o p q r s';
   490    490   } {{a b c d e f g h i j k l m n o p q r s t u v w x y m}}
   491    491   
          492  +set tokenizers {1 simple}
          493  +ifcapable icu { lappend tokenizers 2 {icu en_US} }
          494  +foreach {tn tokenizer} $tokenizers {
          495  +  do_execsql_test 5.$tn.1 "
          496  +    CREATE VIRTUAL TABLE x3 USING FTS4(a, b, TOKENIZE $tokenizer)
          497  +  "
          498  +  do_execsql_test 5.$tn.2 {
          499  +    BEGIN;
          500  +    INSERT INTO x3 VALUES('b b b b b b b b b b b', 'b b b b b b b b b b b b b');
          501  +    INSERT INTO x3 SELECT * FROM x3;
          502  +    INSERT INTO x3 SELECT * FROM x3;
          503  +    INSERT INTO x3 SELECT * FROM x3;
          504  +    INSERT INTO x3 SELECT * FROM x3;
          505  +    INSERT INTO x3 SELECT * FROM x3;
          506  +    INSERT INTO x3 SELECT * FROM x3;
          507  +    INSERT INTO x3 SELECT * FROM x3;
          508  +    INSERT INTO x3 SELECT * FROM x3;
          509  +    INSERT INTO x3 SELECT * FROM x3;
          510  +    INSERT INTO x3 SELECT * FROM x3;
          511  +    INSERT INTO x3 SELECT * FROM x3;
          512  +    INSERT INTO x3 SELECT * FROM x3;
          513  +    INSERT INTO x3 SELECT * FROM x3;
          514  +    INSERT INTO x3 SELECT * FROM x3;
          515  +    INSERT INTO x3 SELECT * FROM x3;
          516  +    INSERT INTO x3 SELECT * FROM x3;
          517  +    INSERT INTO x3 VALUES('a b c', NULL);
          518  +    INSERT INTO x3 VALUES('a x c', NULL);
          519  +    COMMIT;
          520  +
          521  +    SELECT * FROM x3 WHERE x3 MATCH 'a b';
          522  +  } {{a b c} {}}
          523  +
          524  +  do_execsql_test 5.$tn.3 { DROP TABLE x3 }
          525  +}
   492    526   
   493    527   finish_test

Changes to test/fts4merge3.test.

    15     15   set testdir [file dirname $argv0]
    16     16   source $testdir/tester.tcl
    17     17   source $testdir/fts3_common.tcl
    18     18   source $testdir/lock_common.tcl
    19     19   source $testdir/bc_common.tcl
    20     20   
    21     21   set ::testprefix fts4merge3
           22  +
           23  +ifcapable !fts3 {
           24  +  finish_test
           25  +  return
           26  +}
    22     27   
    23     28   if {"" == [bc_find_binaries backcompat.test]} {
    24     29     finish_test
    25     30     return
    26     31   }
    27     32   
    28     33   db close

Changes to test/in.test.

   254    254     }
   255    255   } {}
   256    256   do_test in-7.5 {
   257    257     execsql {
   258    258       SELECT a FROM t1 WHERE a IN (5) AND b NOT IN ();
   259    259     }
   260    260   } {5}
   261         -do_test in-7.6 {
          261  +do_test in-7.6.1 {
   262    262     execsql {
   263    263       SELECT a FROM ta WHERE a IN ();
   264    264     }
   265    265   } {}
          266  +do_test in-7.6.2 {
          267  +  db status step
          268  +} {0}
   266    269   do_test in-7.7 {
   267    270     execsql {
   268    271       SELECT a FROM ta WHERE a NOT IN ();
   269    272     }
   270    273   } {1 2 3 4 6 8 10}
          274  +
          275  +do_test in-7.8.1 {
          276  +  execsql {
          277  +    SELECT * FROM ta LEFT JOIN tb ON (ta.b=tb.b) WHERE ta.a IN ();
          278  +  }
          279  +} {}
          280  +do_test in-7.8.2 {
          281  +  db status step
          282  +} {0}
   271    283   
   272    284   do_test in-8.1 {
   273    285     execsql {
   274    286       SELECT b FROM t1 WHERE a IN ('hello','there')
   275    287     }
   276    288   } {world}
   277    289   do_test in-8.2 {

Changes to test/quota2.test.

    79     79   do_test quota2-1.1 {
    80     80     set ::h1 [sqlite3_quota_fopen quota2a/xyz.txt w+b]
    81     81     sqlite3_quota_fwrite $::h1 1 7000 $bigtext
    82     82   } {4000}
    83     83   do_test quota2-1.2 {
    84     84     set ::quota
    85     85   } {PWD/quota2a/xyz.txt 4000 7000}
           86  +do_test quota2-1.2.1 {
           87  +  sqlite3_quota_file_size $::h1
           88  +} {4000}
           89  +do_test quota2-1.2.2 {
           90  +  sqlite3_quota_fflush $::h1 1
           91  +  sqlite3_quota_file_truesize $::h1
           92  +} {4000}
    86     93   do_test quota2-1.3 {
    87     94     sqlite3_quota_rewind $::h1
    88     95     set ::x [sqlite3_quota_fread $::h1 1001 7]
    89     96     string length $::x
    90     97   } {3003}
    91     98   do_test quota2-1.4 {
    92     99     string match $::x [string range $::bigtext 0 3002]
................................................................................
   115    122     sqlite3_quota_rewind $::h1
   116    123     sqlite3_quota_ftell $::h1
   117    124   } {0}
   118    125   do_test quota2-1.11 {
   119    126     standard_path [sqlite3_quota_dump]
   120    127   } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 1 0}}}
   121    128   do_test quota2-1.12 {
          129  +  sqlite3_quota_ftruncate $::h1 3500
          130  +  sqlite3_quota_file_size $::h1
          131  +} {3500}
          132  +do_test quota2-1.13 {
          133  +  sqlite3_quota_file_truesize $::h1
          134  +} {3500}
          135  +do_test quota2-1.14 {
          136  +  standard_path [sqlite3_quota_dump]
          137  +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 3500 {PWD/quota2a/xyz.txt 3500 1 0}}}
          138  +do_test quota2-1.15 {
          139  +  sqlite3_quota_fseek $::h1 0 SEEK_END
          140  +  sqlite3_quota_ftell $::h1
          141  +} {3500}
          142  +do_test quota2-1.16 {
          143  +  sqlite3_quota_fwrite $::h1 1 7000 $bigtext
          144  +} {500}
          145  +do_test quota2-1.17 {
          146  +  sqlite3_quota_ftell $::h1
          147  +} {4000}
          148  +do_test quota2-1.18 {
          149  +  sqlite3_quota_file_size $::h1
          150  +} {4000}
          151  +do_test quota2-1.19 {
          152  +  sqlite3_quota_fflush $::h1 1
          153  +  sqlite3_quota_file_truesize $::h1
          154  +} {4000}
          155  +do_test quota2-1.20 {
   122    156     sqlite3_quota_fclose $::h1
   123    157     standard_path [sqlite3_quota_dump]
   124    158   } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 0 0}}}
   125         -do_test quota2-1.13 {
          159  +do_test quota2-1.21 {
   126    160     sqlite3_quota_remove quota2a/xyz.txt
   127    161     standard_path [sqlite3_quota_dump]
   128    162   } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}}
          163  +
   129    164   
   130    165   
   131    166   set quota {}
   132    167   do_test quota2-2.1 {
   133    168     set ::h1 [sqlite3_quota_fopen quota2c/xyz.txt w+b]
   134    169     sqlite3_quota_fwrite $::h1 1 7000 $bigtext
   135    170   } {7000}

Added test/savepoint7.test.

            1  +# 2012 March 31
            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  +# Focus on the interaction between RELEASE and ROLLBACK TO with
           13  +# pending query aborts.  See ticket [27ca74af3c083f787a1c44b11fbb7c53bdbbcf1e].
           14  +#
           15  +
           16  +set testdir [file dirname $argv0]
           17  +source $testdir/tester.tcl
           18  +
           19  +# The RELEASE of an inner savepoint should not effect pending queries.
           20  +#
           21  +do_test savepoint7-1.1 {
           22  +  db eval {
           23  +    CREATE TABLE t1(a,b,c);
           24  +    CREATE TABLE t2(x,y,z);
           25  +    INSERT INTO t1 VALUES(1,2,3);
           26  +    INSERT INTO t1 VALUES(4,5,6);
           27  +    INSERT INTO t1 VALUES(7,8,9);
           28  +    SAVEPOINT x1;
           29  +  }
           30  +  db eval {SELECT * FROM t1} {
           31  +    db eval {
           32  +      SAVEPOINT x2;
           33  +      INSERT INTO t2 VALUES($a,$b,$c);
           34  +      RELEASE x2;
           35  +    }
           36  +  }
           37  +  db eval {SELECT * FROM t2; RELEASE x1}
           38  +} {1 2 3 4 5 6 7 8 9}
           39  +
           40  +do_test savepoint7-1.2 {
           41  +  db eval {DELETE FROM t2;}
           42  +  db eval {SELECT * FROM t1} {
           43  +    db eval {
           44  +      SAVEPOINT x2;
           45  +      INSERT INTO t2 VALUES($a,$b,$c);
           46  +      RELEASE x2;
           47  +    }
           48  +  }
           49  +  db eval {SELECT * FROM t2}
           50  +} {1 2 3 4 5 6 7 8 9}
           51  +
           52  +do_test savepoint7-1.3 {
           53  +  db eval {DELETE FROM t2; BEGIN;}
           54  +  db eval {SELECT * FROM t1} {
           55  +    db eval {
           56  +      SAVEPOINT x2;
           57  +      INSERT INTO t2 VALUES($a,$b,$c);
           58  +      RELEASE x2;
           59  +    }
           60  +  }
           61  +  db eval {SELECT * FROM t2; ROLLBACK;}
           62  +} {1 2 3 4 5 6 7 8 9}
           63  +
           64  +# However, a ROLLBACK of an inner savepoint will abort all queries, including
           65  +# queries in outer contexts.
           66  +#
           67  +do_test savepoint7-2.1 {
           68  +  db eval {DELETE FROM t2; SAVEPOINT x1;}
           69  +  set rc [catch {
           70  +    db eval {SELECT * FROM t1} {
           71  +      db eval {
           72  +        SAVEPOINT x2;
           73  +        INSERT INTO t2 VALUES($a,$b,$c);
           74  +        ROLLBACK TO x2;
           75  +      }
           76  +    }
           77  +  } msg]
           78  +  db eval {RELEASE x1}
           79  +  list $rc $msg [db eval {SELECT * FROM t2}]
           80  +} {1 {callback requested query abort} {}}
           81  +
           82  +do_test savepoint7-2.2 {
           83  +  db eval {DELETE FROM t2;}
           84  +  set rc [catch {
           85  +    db eval {SELECT * FROM t1} {
           86  +      db eval {
           87  +        SAVEPOINT x2;
           88  +        INSERT INTO t2 VALUES($a,$b,$c);
           89  +        ROLLBACK TO x2;
           90  +      }
           91  +    }
           92  +  } msg]
           93  +  list $rc $msg [db eval {SELECT * FROM t2}]
           94  +} {1 {callback requested query abort} {}}
           95  +
           96  +finish_test

Changes to test/subquery.test.

   326    326     }
   327    327   } {1 one 2 two}
   328    328   do_test subquery-3.3.5 {
   329    329     execsql {
   330    330       SELECT a, (SELECT count(*) FROM t2 WHERE a=c) FROM t1;
   331    331     }
   332    332   } {1 1 2 1}
          333  +
          334  +# The following tests check for aggregate subqueries in an aggregate
          335  +# query.
          336  +#
          337  +do_test subquery-3.4.1 {
          338  +  execsql {
          339  +    CREATE TABLE t34(x,y);
          340  +    INSERT INTO t34 VALUES(106,4), (107,3), (106,5), (107,5);
          341  +    SELECT a.x, avg(a.y)
          342  +      FROM t34 AS a
          343  +     GROUP BY a.x
          344  +     HAVING NOT EXISTS( SELECT b.x, avg(b.y)
          345  +                          FROM t34 AS b
          346  +                         GROUP BY b.x
          347  +                         HAVING avg(a.y) > avg(b.y));
          348  +  }
          349  +} {107 4.0}
          350  +do_test subquery-3.4.2 {
          351  +  execsql {
          352  +    SELECT a.x, avg(a.y) AS avg1
          353  +      FROM t34 AS a
          354  +     GROUP BY a.x
          355  +     HAVING NOT EXISTS( SELECT b.x, avg(b.y) AS avg2
          356  +                          FROM t34 AS b
          357  +                         GROUP BY b.x
          358  +                         HAVING avg1 > avg2);
          359  +  }
          360  +} {107 4.0}
          361  +do_test subquery-3.4.3 {
          362  +  execsql {
          363  +    SELECT
          364  +       a.x,
          365  +       avg(a.y),
          366  +       NOT EXISTS ( SELECT b.x, avg(b.y)
          367  +                      FROM t34 AS b
          368  +                      GROUP BY b.x
          369  +                     HAVING avg(a.y) > avg(b.y)),
          370  +       EXISTS ( SELECT c.x, avg(c.y)
          371  +                  FROM t34 AS c
          372  +                  GROUP BY c.x
          373  +                 HAVING avg(a.y) > avg(c.y))
          374  +      FROM t34 AS a
          375  +     GROUP BY a.x
          376  +     ORDER BY a.x;
          377  +  }
          378  +} {106 4.5 0 1 107 4.0 1 0}
          379  +
   333    380   
   334    381   #------------------------------------------------------------------
   335    382   # These tests - subquery-4.* - use the TCL statement cache to try 
   336    383   # and expose bugs to do with re-using statements that have been 
   337    384   # passed to sqlite3_reset().
   338    385   #
   339    386   # One problem was that VDBE memory cells were not being initialised

Changes to tool/build-shell.sh.

     8      8   # ~/sqlite/bld.  There should be an appropriate Makefile in the current
     9      9   # directory as well.
    10     10   #
    11     11   make sqlite3.c
    12     12   gcc -o sqlite3 -g -Os -I. \
    13     13      -DSQLITE_THREADSAFE=0 \
    14     14      -DSQLITE_ENABLE_VFSTRACE \
    15         -   -DSQLITE_ENABLE_STAT2 \
    16         -   -DSQLITE_ENABLE_FTS3 \
           15  +   -DSQLITE_ENABLE_STAT3 \
           16  +   -DSQLITE_ENABLE_FTS4 \
    17     17      -DSQLITE_ENABLE_RTREE \
    18     18      -DHAVE_READLINE \
    19     19      -DHAVE_USLEEP=1 \
    20     20      ../sqlite/src/shell.c ../sqlite/src/test_vfstrace.c \
    21     21      sqlite3.c -ldl -lreadline -lncurses

Changes to tool/showdb.c.

     5      5   #include <ctype.h>
     6      6   #include <sys/types.h>
     7      7   #include <sys/stat.h>
     8      8   #include <fcntl.h>
     9      9   #include <unistd.h>
    10     10   #include <stdlib.h>
    11     11   #include <string.h>
           12  +#include "sqlite3.h"
    12     13   
    13     14   
    14     15   static int pagesize = 1024;     /* Size of a database page */
    15     16   static int db = -1;             /* File descriptor for reading the DB */
    16     17   static int mxPage = 0;          /* Last page number */
    17     18   static int perLine = 16;        /* HEX elements to print per line */
    18     19   
................................................................................
   445    446         pgno = 0;
   446    447       }else{
   447    448         pgno = (int)decodeInt32(&a[0]);
   448    449       }
   449    450       free(a);
   450    451     }
   451    452   }
          453  +
          454  +/*
          455  +** A short text comment on the use of each page.
          456  +*/
          457  +static char **zPageUse;
          458  +
          459  +/*
          460  +** Add a comment on the use of a page.
          461  +*/
          462  +static void page_usage_msg(int pgno, const char *zFormat, ...){
          463  +  va_list ap;
          464  +  char *zMsg;
          465  +
          466  +  va_start(ap, zFormat);
          467  +  zMsg = sqlite3_vmprintf(zFormat, ap);
          468  +  va_end(ap);
          469  +  if( pgno<=0 || pgno>mxPage ){
          470  +    printf("ERROR: page %d out of bounds.  Range=1..%d.  Msg: %s\n",
          471  +            pgno, mxPage, zMsg);
          472  +    sqlite3_free(zMsg);
          473  +    return;
          474  +  }
          475  +  if( zPageUse[pgno]!=0 ){
          476  +    printf("ERROR: page %d used multiple times:\n", pgno);
          477  +    printf("ERROR:    previous: %s\n", zPageUse[pgno]);
          478  +    printf("ERROR:    current:  %s\n", zPageUse[pgno]);
          479  +    sqlite3_free(zPageUse[pgno]);
          480  +  }
          481  +  zPageUse[pgno] = zMsg;
          482  +}
          483  +
          484  +/*
          485  +** Find overflow pages of a cell and describe their usage.
          486  +*/
          487  +static void page_usage_cell(
          488  +  unsigned char cType,    /* Page type */
          489  +  unsigned char *a,       /* Cell content */
          490  +  int pgno,               /* page containing the cell */
          491  +  int cellno              /* Index of the cell on the page */
          492  +){
          493  +  int i;
          494  +  int nDesc = 0;
          495  +  int n = 0;
          496  +  i64 nPayload;
          497  +  i64 rowid;
          498  +  int nLocal;
          499  +  i = 0;
          500  +  if( cType<=5 ){
          501  +    a += 4;
          502  +    n += 4;
          503  +  }
          504  +  if( cType!=5 ){
          505  +    i = decodeVarint(a, &nPayload);
          506  +    a += i;
          507  +    n += i;
          508  +    nLocal = localPayload(nPayload, cType);
          509  +  }else{
          510  +    nPayload = nLocal = 0;
          511  +  }
          512  +  if( cType==5 || cType==13 ){
          513  +    i = decodeVarint(a, &rowid);
          514  +    a += i;
          515  +    n += i;
          516  +  }
          517  +  if( nLocal<nPayload ){
          518  +    int ovfl = decodeInt32(a+nLocal);
          519  +    int cnt = 0;
          520  +    while( ovfl && (cnt++)<mxPage ){
          521  +      page_usage_msg(ovfl, "overflow %d from cell %d of page %d",
          522  +                     cnt, cellno, pgno);
          523  +      a = getContent((ovfl-1)*pagesize, 4);
          524  +      ovfl = decodeInt32(a);
          525  +      free(a);
          526  +    }
          527  +  }
          528  +}
          529  +
          530  +
          531  +/*
          532  +** Describe the usages of a b-tree page
          533  +*/
          534  +static void page_usage_btree(
          535  +  int pgno,             /* Page to describe */
          536  +  int parent,           /* Parent of this page.  0 for root pages */
          537  +  int idx,              /* Which child of the parent */
          538  +  const char *zName     /* Name of the table */
          539  +){
          540  +  unsigned char *a;
          541  +  const char *zType = "corrupt node";
          542  +  int nCell;
          543  +  int i;
          544  +  int hdr = pgno==1 ? 100 : 0;
          545  +
          546  +  if( pgno<=0 || pgno>mxPage ) return;
          547  +  a = getContent((pgno-1)*pagesize, pagesize);
          548  +  switch( a[hdr] ){
          549  +    case 2:  zType = "interior node of index";  break;
          550  +    case 5:  zType = "interior node of table";  break;
          551  +    case 10: zType = "leaf of index";           break;
          552  +    case 13: zType = "leaf of table";           break;
          553  +  }
          554  +  if( parent ){
          555  +    page_usage_msg(pgno, "%s [%s], child %d of page %d",
          556  +                   zType, zName, idx, parent);
          557  +  }else{
          558  +    page_usage_msg(pgno, "root %s [%s]", zType, zName);
          559  +  }
          560  +  nCell = a[hdr+3]*256 + a[hdr+4];
          561  +  if( a[hdr]==2 || a[hdr]==5 ){
          562  +    int cellstart = hdr+12;
          563  +    unsigned int child;
          564  +    for(i=0; i<nCell; i++){
          565  +      int ofst;
          566  +
          567  +      ofst = cellstart + i*2;
          568  +      ofst = a[ofst]*256 + a[ofst+1];
          569  +      child = decodeInt32(a+ofst);
          570  +      page_usage_btree(child, pgno, i, zName);
          571  +    }
          572  +    child = decodeInt32(a+cellstart-4);
          573  +    page_usage_btree(child, pgno, i, zName);
          574  +  }
          575  +  if( a[hdr]==2 || a[hdr]==10 || a[hdr]==13 ){
          576  +    int cellstart = hdr + 8 + 4*(a[hdr]<=5);
          577  +    for(i=0; i<nCell; i++){
          578  +      int ofst;
          579  +      ofst = cellstart + i*2;
          580  +      ofst = a[ofst]*256 + a[ofst+1];
          581  +      page_usage_cell(a[hdr], a+ofst, pgno, i);
          582  +    }
          583  +  }
          584  +  free(a);
          585  +}
          586  +
          587  +/*
          588  +** Determine page usage by the freelist
          589  +*/
          590  +static void page_usage_freelist(int pgno){
          591  +  unsigned char *a;
          592  +  int cnt = 0;
          593  +  int i;
          594  +  int n;
          595  +  int iNext;
          596  +  int parent = 1;
          597  +
          598  +  while( pgno>0 && pgno<=mxPage && (cnt++)<mxPage ){
          599  +    page_usage_msg(pgno, "freelist trunk #%d child of %d", cnt, parent);
          600  +    a = getContent((pgno-1)*pagesize, pagesize);
          601  +    iNext = decodeInt32(a);
          602  +    n = decodeInt32(a+4);
          603  +    for(i=0; i<n; i++){
          604  +      int child = decodeInt32(a + (i*4+8));
          605  +      page_usage_msg(child, "freelist leaf, child %d of trunk page %d",
          606  +                     i, pgno);
          607  +    }
          608  +    free(a);
          609  +    parent = pgno;
          610  +    pgno = iNext;
          611  +  }
          612  +}
          613  +
          614  +/*
          615  +** Try to figure out how every page in the database file is being used.
          616  +*/
          617  +static void page_usage_report(const char *zDbName){
          618  +  int i;
          619  +  int rc;
          620  +  sqlite3 *db;
          621  +  sqlite3_stmt *pStmt;
          622  +  unsigned char *a;
          623  +
          624  +  /* Avoid the pathological case */
          625  +  if( mxPage<1 ){
          626  +    printf("empty database\n");
          627  +    return;
          628  +  }
          629  +
          630  +  /* Open the database file */
          631  +  rc = sqlite3_open(zDbName, &db);
          632  +  if( rc ){
          633  +    printf("cannot open database: %s\n", sqlite3_errmsg(db));
          634  +    sqlite3_close(db);
          635  +    return;
          636  +  }
          637  +
          638  +  /* Set up global variables zPageUse[] and mxPage to record page
          639  +  ** usages */
          640  +  zPageUse = sqlite3_malloc( sizeof(zPageUse[0])*(mxPage+1) );
          641  +  if( zPageUse==0 ) out_of_memory();
          642  +  memset(zPageUse, 0, sizeof(zPageUse[0])*(mxPage+1));
          643  +
          644  +  /* Discover the usage of each page */
          645  +  a = getContent(0, 100);
          646  +  page_usage_freelist(decodeInt32(a+32));
          647  +  free(a);
          648  +  page_usage_btree(1, 0, 0, "sqlite_master");
          649  +  rc = sqlite3_prepare_v2(db,
          650  +           "SELECT type, name, rootpage FROM SQLITE_MASTER WHERE rootpage",
          651  +           -1, &pStmt, 0);
          652  +  if( rc==SQLITE_OK ){
          653  +    while( sqlite3_step(pStmt)==SQLITE_ROW ){
          654  +      int pgno = sqlite3_column_int(pStmt, 2);
          655  +      page_usage_btree(pgno, 0, 0, sqlite3_column_text(pStmt, 1));
          656  +    }
          657  +  }else{
          658  +    printf("ERROR: cannot query database: %s\n", sqlite3_errmsg(db));
          659  +  }
          660  +  sqlite3_finalize(pStmt);
          661  +  sqlite3_close(db);
          662  +
          663  +  /* Print the report and free memory used */
          664  +  for(i=1; i<=mxPage; i++){
          665  +    printf("%5d: %s\n", i, zPageUse[i] ? zPageUse[i] : "???");
          666  +    sqlite3_free(zPageUse[i]);
          667  +  }
          668  +  sqlite3_free(zPageUse);
          669  +  zPageUse = 0;
          670  +}
   452    671   
   453    672   /*
   454    673   ** Print a usage comment
   455    674   */
   456    675   static void usage(const char *argv0){
   457    676     fprintf(stderr, "Usage %s FILENAME ?args...?\n\n", argv0);
   458    677     fprintf(stderr,
   459    678       "args:\n"
   460    679       "    dbheader        Show database header\n"
          680  +    "    pgidx           Index of how each page is used\n"
   461    681       "    NNN..MMM        Show hex of pages NNN through MMM\n"
   462    682       "    NNN..end        Show hex of pages NNN through end of file\n"
   463    683       "    NNNb            Decode btree page NNN\n"
   464    684       "    NNNbc           Decode btree page NNN and show content\n"
   465    685       "    NNNbm           Decode btree page NNN and show a layout map\n"
   466    686       "    NNNt            Decode freelist trunk page NNN\n"
   467    687       "    NNNtd           Show leaf freelist pages on the decode\n"
................................................................................
   498    718       int i;
   499    719       for(i=2; i<argc; i++){
   500    720         int iStart, iEnd;
   501    721         char *zLeft;
   502    722         if( strcmp(argv[i], "dbheader")==0 ){
   503    723           print_db_header();
   504    724           continue;
          725  +      }
          726  +      if( strcmp(argv[i], "pgidx")==0 ){
          727  +        page_usage_report(argv[1]);
          728  +        continue;
   505    729         }
   506    730         if( !isdigit(argv[i][0]) ){
   507    731           fprintf(stderr, "%s: unknown option: [%s]\n", argv[0], argv[i]);
   508    732           continue;
   509    733         }
   510    734         iStart = strtol(argv[i], &zLeft, 0);
   511    735         if( zLeft && strcmp(zLeft,"..end")==0 ){

Changes to tool/spaceanal.tcl.

    45     45   }
    46     46   
    47     47   # Compute the total file size assuming test_multiplexor is being used.
    48     48   # Assume that SQLITE_ENABLE_8_3_NAMES might be enabled
    49     49   #
    50     50   set extension [file extension $file_to_analyze]
    51     51   set pattern $file_to_analyze
    52         -append pattern {[0-9][0-9]}
           52  +append pattern {[0-3][0-9][0-9]}
    53     53   foreach f [glob -nocomplain $pattern] {
    54     54     incr true_file_size [file size $f]
    55     55     set extension {}
    56     56   }
    57     57   if {[string length $extension]>=2 && [string length $extension]<=4} {
    58     58     set pattern [file rootname $file_to_analyze]
    59         -  append pattern [string range $extension 0 1]
    60         -  append pattern {[0-9][0-9]}
           59  +  append pattern {.[0-3][0-9][0-9]}
    61     60     foreach f [glob -nocomplain $pattern] {
    62     61       incr true_file_size [file size $f]
    63     62     }
    64     63   }
    65     64   
    66     65   # Open the database
    67     66   #

Changes to tool/warnings-clang.sh.

     5      5   #
     6      6   rm -f sqlite3.c
     7      7   make sqlite3.c
     8      8   echo '************* FTS4 and RTREE ****************'
     9      9   scan-build gcc -c -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \
    10     10         -DSQLITE_DEBUG sqlite3.c 2>&1 | grep -v 'ANALYZE:'
    11     11   echo '********** ENABLE_STAT3. THREADSAFE=0 *******'
    12         -scan-build gcc -c -DSQLITE_ENABLE_STAT3 -DSQLITE_THREADSAFE=0 \
    13         -      -DSQLITE_DEBUG sqlite3.c 2>&1 | grep -v 'ANALYZE:'
           12  +scan-build gcc -c -I. -DSQLITE_ENABLE_STAT3 -DSQLITE_THREADSAFE=0 \
           13  +      -DSQLITE_DEBUG \
           14  +      sqlite3.c ../sqlite/src/shell.c -ldl 2>&1 | grep -v 'ANALYZE:'