/ Check-in [87a0eab5]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Import all the latest trunk changes into the sessions branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: 87a0eab5d98fff93aa2147c04c4af27be42fb365
User & Date: drh 2012-04-18 01:41:37
Context
2012-04-19
20:00
Merge the latest trunk changes into the sessions branch. check-in: 2b7a91e6 user: drh tags: sessions
2012-04-18
01:41
Import all the latest trunk changes into the sessions branch. check-in: 87a0eab5 user: drh tags: sessions
2012-04-17
16:38
Improved handling of aggregate subqueries within an aggregate query. check-in: 430bb59d user: drh tags: trunk
2012-03-30
17:30
Merge all recent trunk changes into the sessions branch. check-in: fb9b9987 user: drh tags: sessions
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_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;
................................................................................
   526    527         "fts3_configure_incr_load", fts3_configure_incr_load_cmd, 0, 0
   527    528     );
   528    529     Tcl_CreateObjCommand(
   529    530         interp, "fts3_test_tokenizer", fts3_test_tokenizer_cmd, 0, 0
   530    531     );
   531    532     return TCL_OK;
   532    533   }
          534  +#endif                  /* SQLITE_ENABLE_FTS3 || SQLITE_ENABLE_FTS4 */
   533    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/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.

  1214   1214     }
  1215   1215   
  1216   1216     /* Test all CHECK constraints
  1217   1217     */
  1218   1218   #ifndef SQLITE_OMIT_CHECK
  1219   1219     if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
  1220   1220       ExprList *pCheck = pTab->pCheck;
  1221         -    int i;
  1222   1221       pParse->ckBase = regData;
  1223   1222       onError = overrideError!=OE_Default ? overrideError : OE_Abort;
  1224   1223       for(i=0; i<pCheck->nExpr; i++){
  1225   1224         int allOk = sqlite3VdbeMakeLabel(v);
  1226   1225         sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
  1227   1226         if( onError==OE_Ignore ){
  1228   1227           sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);

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/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.

  2015   2015     SrcList *pSrcList;   /* One or more tables used to resolve names */
  2016   2016     ExprList *pEList;    /* Optional list of named expressions */
  2017   2017     int nRef;            /* Number of names resolved by this context */
  2018   2018     int nErr;            /* Number of errors encountered while resolving names */
  2019   2019     u8 allowAgg;         /* Aggregate functions allowed here */
  2020   2020     u8 hasAgg;           /* True if aggregates are seen */
  2021   2021     u8 isCheck;          /* True if resolving names in a CHECK constraint */
  2022         -  int nDepth;          /* Depth of subquery recursion. 1 for no recursion */
  2023   2022     AggInfo *pAggInfo;   /* Information about aggregates at this level */
  2024   2023     NameContext *pNext;  /* Next outer name context.  NULL for outermost */
  2025   2024   };
  2026   2025   
  2027   2026   /*
  2028   2027   ** An instance of the following structure contains all information
  2029   2028   ** needed to generate code for a single SELECT statement.
................................................................................
  2485   2484   struct Walker {
  2486   2485     int (*xExprCallback)(Walker*, Expr*);     /* Callback for expressions */
  2487   2486     int (*xSelectCallback)(Walker*,Select*);  /* Callback for SELECTs */
  2488   2487     Parse *pParse;                            /* Parser context.  */
  2489   2488     union {                                   /* Extra data for callback */
  2490   2489       NameContext *pNC;                          /* Naming context */
  2491   2490       int i;                                     /* Integer value */
         2491  +    SrcList *pSrcList;                         /* FROM clause */
  2492   2492     } u;
  2493   2493   };
  2494   2494   
  2495   2495   /* Forward declarations */
  2496   2496   int sqlite3WalkExpr(Walker*, Expr*);
  2497   2497   int sqlite3WalkExprList(Walker*, ExprList*);
  2498   2498   int sqlite3WalkSelect(Walker*, Select*);
................................................................................
  2853   2853   void sqlite3HaltConstraint(Parse*, int, char*, int);
  2854   2854   Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
  2855   2855   ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
  2856   2856   SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
  2857   2857   IdList *sqlite3IdListDup(sqlite3*,IdList*);
  2858   2858   Select *sqlite3SelectDup(sqlite3*,Select*,int);
  2859   2859   void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
  2860         -FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,int);
         2860  +FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
  2861   2861   void sqlite3RegisterBuiltinFunctions(sqlite3*);
  2862   2862   void sqlite3RegisterDateTimeFunctions(void);
  2863   2863   void sqlite3RegisterGlobalFunctions(void);
  2864   2864   int sqlite3SafetyCheckOk(sqlite3*);
  2865   2865   int sqlite3SafetyCheckSickOrOk(sqlite3*);
  2866   2866   void sqlite3ChangeCookie(Parse*, int);
  2867   2867   

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_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   }

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();
................................................................................
  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/vdbe.c.

  2740   2740             p->rc = rc = SQLITE_BUSY;
  2741   2741             goto vdbe_return;
  2742   2742           }
  2743   2743           db->isTransactionSavepoint = 0;
  2744   2744           rc = p->rc;
  2745   2745         }else{
  2746   2746           iSavepoint = db->nSavepoint - iSavepoint - 1;
  2747         -        for(ii=0; ii<db->nDb; ii++){
  2748         -          sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, SQLITE_ABORT);
         2747  +        if( p1==SAVEPOINT_ROLLBACK ){
         2748  +          for(ii=0; ii<db->nDb; ii++){
         2749  +            sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, SQLITE_ABORT);
         2750  +          }
  2749   2751           }
  2750   2752           for(ii=0; ii<db->nDb; ii++){
  2751   2753             rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
  2752   2754             if( rc!=SQLITE_OK ){
  2753   2755               goto abort_due_to_error;
  2754   2756             }
  2755   2757           }

Changes to src/vdbeaux.c.

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

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/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.

    72     72   do_test quota2-1.1 {
    73     73     set ::h1 [sqlite3_quota_fopen quota2a/xyz.txt w+b]
    74     74     sqlite3_quota_fwrite $::h1 1 7000 $bigtext
    75     75   } {4000}
    76     76   do_test quota2-1.2 {
    77     77     set ::quota
    78     78   } {PWD/quota2a/xyz.txt 4000 7000}
           79  +do_test quota2-1.2.1 {
           80  +  sqlite3_quota_file_size $::h1
           81  +} {4000}
           82  +do_test quota2-1.2.2 {
           83  +  sqlite3_quota_fflush $::h1 1
           84  +  sqlite3_quota_file_truesize $::h1
           85  +} {4000}
    79     86   do_test quota2-1.3 {
    80     87     sqlite3_quota_rewind $::h1
    81     88     set ::x [sqlite3_quota_fread $::h1 1001 7]
    82     89     string length $::x
    83     90   } {3003}
    84     91   do_test quota2-1.4 {
    85     92     string match $::x [string range $::bigtext 0 3002]
................................................................................
   108    115     sqlite3_quota_rewind $::h1
   109    116     sqlite3_quota_ftell $::h1
   110    117   } {0}
   111    118   do_test quota2-1.11 {
   112    119     standard_path [sqlite3_quota_dump]
   113    120   } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 1 0}}}
   114    121   do_test quota2-1.12 {
          122  +  sqlite3_quota_ftruncate $::h1 3500
          123  +  sqlite3_quota_file_size $::h1
          124  +} {3500}
          125  +do_test quota2-1.13 {
          126  +  sqlite3_quota_file_truesize $::h1
          127  +} {3500}
          128  +do_test quota2-1.14 {
          129  +  standard_path [sqlite3_quota_dump]
          130  +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 3500 {PWD/quota2a/xyz.txt 3500 1 0}}}
          131  +do_test quota2-1.15 {
          132  +  sqlite3_quota_fseek $::h1 0 SEEK_END
          133  +  sqlite3_quota_ftell $::h1
          134  +} {3500}
          135  +do_test quota2-1.16 {
          136  +  sqlite3_quota_fwrite $::h1 1 7000 $bigtext
          137  +} {500}
          138  +do_test quota2-1.17 {
          139  +  sqlite3_quota_ftell $::h1
          140  +} {4000}
          141  +do_test quota2-1.18 {
          142  +  sqlite3_quota_file_size $::h1
          143  +} {4000}
          144  +do_test quota2-1.19 {
          145  +  sqlite3_quota_fflush $::h1 1
          146  +  sqlite3_quota_file_truesize $::h1
          147  +} {4000}
          148  +do_test quota2-1.20 {
   115    149     sqlite3_quota_fclose $::h1
   116    150     standard_path [sqlite3_quota_dump]
   117    151   } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 0 0}}}
   118         -do_test quota2-1.13 {
          152  +do_test quota2-1.21 {
   119    153     sqlite3_quota_remove quota2a/xyz.txt
   120    154     standard_path [sqlite3_quota_dump]
   121    155   } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}}
          156  +
   122    157   
   123    158   
   124    159   set quota {}
   125    160   do_test quota2-2.1 {
   126    161     set ::h1 [sqlite3_quota_fopen quota2c/xyz.txt w+b]
   127    162     sqlite3_quota_fwrite $::h1 1 7000 $bigtext
   128    163   } {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:'