/ Check-in [0f66a093]
Login

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

Overview
Comment:Update this branch with latest trunk changes.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | schemalint
Files: files | file ages | folders
SHA3-256:0f66a093935100efd731e14aa63b57360ddd517c1ac97edd1ea9a9de95e1f3cc
User & Date: dan 2017-04-11 19:00:30
Context
2017-04-13
16:19
Update this branch with latest changes from trunk. check-in: 5fcd840c user: dan tags: schemalint
2017-04-11
19:00
Update this branch with latest trunk changes. check-in: 0f66a093 user: dan tags: schemalint
18:29
Fix a formatting issue in the output of the sqlite3_expert program. check-in: cc8c3581 user: dan tags: schemalint
18:06
Smaller and faster implementation of exprMightBeIndexed(). check-in: 76cd611d user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/misc/json1.c.

   781    781       return j+1;
   782    782     }else if( c=='"' ){
   783    783       /* Parse string */
   784    784       u8 jnFlags = 0;
   785    785       j = i+1;
   786    786       for(;;){
   787    787         c = z[j];
   788         -      if( c==0 ) return -1;
          788  +      if( c<=0x1f ) return -1;  /* Control characters not allowed in strings */
   789    789         if( c=='\\' ){
   790    790           c = z[++j];
   791    791           if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
   792    792              || c=='n' || c=='r' || c=='t'
   793    793              || (c=='u' && jsonIs4Hex(z+j+1)) ){
   794    794             jnFlags = JNODE_ESCAPE;
   795    795           }else{

Changes to src/btree.h.

   272    272   ** organized and understandable, and it also helps the resulting code to
   273    273   ** run a little faster by using fewer registers for parameter passing.
   274    274   */
   275    275   struct BtreePayload {
   276    276     const void *pKey;       /* Key content for indexes.  NULL for tables */
   277    277     sqlite3_int64 nKey;     /* Size of pKey for indexes.  PRIMARY KEY for tabs */
   278    278     const void *pData;      /* Data for tables.  NULL for indexes */
   279         -  struct Mem *aMem;       /* First of nMem value in the unpacked pKey */
          279  +  sqlite3_value *aMem;    /* First of nMem value in the unpacked pKey */
   280    280     u16 nMem;               /* Number of aMem[] value.  Might be zero */
   281    281     int nData;              /* Size of pData.  0 if none. */
   282    282     int nZero;              /* Extra zero data appended after pData,nData */
   283    283   };
   284    284   
   285    285   int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
   286    286                          int flags, int seekResult);

Changes to src/expr.c.

    54     54     if( op==TK_REGISTER ) op = pExpr->op2;
    55     55   #ifndef SQLITE_OMIT_CAST
    56     56     if( op==TK_CAST ){
    57     57       assert( !ExprHasProperty(pExpr, EP_IntValue) );
    58     58       return sqlite3AffinityType(pExpr->u.zToken, 0);
    59     59     }
    60     60   #endif
    61         -  if( op==TK_AGG_COLUMN || op==TK_COLUMN ){
           61  +  if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){
    62     62       return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
    63     63     }
    64     64     if( op==TK_SELECT_COLUMN ){
    65     65       assert( pExpr->pLeft->flags&EP_xIsSelect );
    66     66       return sqlite3ExprAffinity(
    67     67           pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
    68     68       );
................................................................................
  3188   3188   void sqlite3ExprCodeGetColumnOfTable(
  3189   3189     Vdbe *v,        /* The VDBE under construction */
  3190   3190     Table *pTab,    /* The table containing the value */
  3191   3191     int iTabCur,    /* The table cursor.  Or the PK cursor for WITHOUT ROWID */
  3192   3192     int iCol,       /* Index of the column to extract */
  3193   3193     int regOut      /* Extract the value into this register */
  3194   3194   ){
         3195  +  if( pTab==0 ){
         3196  +    sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
         3197  +    return;
         3198  +  }
  3195   3199     if( iCol<0 || iCol==pTab->iPKey ){
  3196   3200       sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
  3197   3201     }else{
  3198   3202       int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
  3199   3203       int x = iCol;
  3200   3204       if( !HasRowid(pTab) && !IsVirtual(pTab) ){
  3201   3205         x = sqlite3ColumnOfIndex(sqlite3PrimaryKeyIndex(pTab), iCol);

Changes to src/select.c.

   108    108     ExprList *pOrderBy,   /* the ORDER BY clause */
   109    109     u32 selFlags,         /* Flag parameters, such as SF_Distinct */
   110    110     Expr *pLimit,         /* LIMIT value.  NULL means not used */
   111    111     Expr *pOffset         /* OFFSET value.  NULL means no offset */
   112    112   ){
   113    113     Select *pNew;
   114    114     Select standin;
   115         -  sqlite3 *db = pParse->db;
   116         -  pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
          115  +  pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) );
   117    116     if( pNew==0 ){
   118         -    assert( db->mallocFailed );
          117  +    assert( pParse->db->mallocFailed );
   119    118       pNew = &standin;
   120    119     }
   121    120     if( pEList==0 ){
   122         -    pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0));
          121  +    pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(pParse->db,TK_ASTERISK,0));
   123    122     }
   124    123     pNew->pEList = pEList;
   125    124     pNew->op = TK_SELECT;
   126    125     pNew->selFlags = selFlags;
   127    126     pNew->iLimit = 0;
   128    127     pNew->iOffset = 0;
   129    128   #if SELECTTRACE_ENABLED
   130    129     pNew->zSelName[0] = 0;
   131    130   #endif
   132    131     pNew->addrOpenEphm[0] = -1;
   133    132     pNew->addrOpenEphm[1] = -1;
   134    133     pNew->nSelectRow = 0;
   135         -  if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc));
          134  +  if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*pSrc));
   136    135     pNew->pSrc = pSrc;
   137    136     pNew->pWhere = pWhere;
   138    137     pNew->pGroupBy = pGroupBy;
   139    138     pNew->pHaving = pHaving;
   140    139     pNew->pOrderBy = pOrderBy;
   141    140     pNew->pPrior = 0;
   142    141     pNew->pNext = 0;
   143    142     pNew->pLimit = pLimit;
   144    143     pNew->pOffset = pOffset;
   145    144     pNew->pWith = 0;
   146         -  assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
   147         -  if( db->mallocFailed ) {
   148         -    clearSelect(db, pNew, pNew!=&standin);
          145  +  assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || pParse->db->mallocFailed!=0 );
          146  +  if( pParse->db->mallocFailed ) {
          147  +    clearSelect(pParse->db, pNew, pNew!=&standin);
   149    148       pNew = 0;
   150    149     }else{
   151    150       assert( pNew->pSrc!=0 || pParse->nErr>0 );
   152    151     }
   153    152     assert( pNew!=&standin );
   154    153     return pNew;
   155    154   }
................................................................................
  1526   1525   ){
  1527   1526   #ifndef SQLITE_OMIT_DECLTYPE
  1528   1527     Vdbe *v = pParse->pVdbe;
  1529   1528     int i;
  1530   1529     NameContext sNC;
  1531   1530     sNC.pSrcList = pTabList;
  1532   1531     sNC.pParse = pParse;
         1532  +  sNC.pNext = 0;
  1533   1533     for(i=0; i<pEList->nExpr; i++){
  1534   1534       Expr *p = pEList->a[i].pExpr;
  1535   1535       const char *zType;
  1536   1536   #ifdef SQLITE_ENABLE_COLUMN_METADATA
  1537   1537       const char *zOrigDb = 0;
  1538   1538       const char *zOrigTab = 0;
  1539   1539       const char *zOrigCol = 0;
................................................................................
  1549   1549   #else
  1550   1550       zType = columnType(&sNC, p, 0, 0, 0, 0);
  1551   1551   #endif
  1552   1552       sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT);
  1553   1553     }
  1554   1554   #endif /* !defined(SQLITE_OMIT_DECLTYPE) */
  1555   1555   }
         1556  +
         1557  +/*
         1558  +** Return the Table objecct in the SrcList that has cursor iCursor.
         1559  +** Or return NULL if no such Table object exists in the SrcList.
         1560  +*/
         1561  +static Table *tableWithCursor(SrcList *pList, int iCursor){
         1562  +  int j;
         1563  +  for(j=0; j<pList->nSrc; j++){
         1564  +    if( pList->a[j].iCursor==iCursor ) return pList->a[j].pTab;
         1565  +  }
         1566  +  return 0;
         1567  +}
         1568  +
  1556   1569   
  1557   1570   /*
  1558   1571   ** Generate code that will tell the VDBE the names of columns
  1559   1572   ** in the result set.  This information is used to provide the
  1560   1573   ** azCol[] values in the callback.
  1561   1574   */
  1562   1575   static void generateColumnNames(
  1563   1576     Parse *pParse,      /* Parser context */
  1564   1577     SrcList *pTabList,  /* List of tables */
  1565   1578     ExprList *pEList    /* Expressions defining the result set */
  1566   1579   ){
  1567   1580     Vdbe *v = pParse->pVdbe;
  1568         -  int i, j;
         1581  +  int i;
         1582  +  Table *pTab;
  1569   1583     sqlite3 *db = pParse->db;
  1570   1584     int fullNames, shortNames;
  1571   1585   
  1572   1586   #ifndef SQLITE_OMIT_EXPLAIN
  1573   1587     /* If this is an EXPLAIN, skip this step */
  1574   1588     if( pParse->explain ){
  1575   1589       return;
................................................................................
  1586   1600     for(i=0; i<pEList->nExpr; i++){
  1587   1601       Expr *p;
  1588   1602       p = pEList->a[i].pExpr;
  1589   1603       if( NEVER(p==0) ) continue;
  1590   1604       if( pEList->a[i].zName ){
  1591   1605         char *zName = pEList->a[i].zName;
  1592   1606         sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
  1593         -    }else if( p->op==TK_COLUMN || p->op==TK_AGG_COLUMN ){
  1594         -      Table *pTab;
         1607  +    }else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN)
         1608  +           && (pTab = tableWithCursor(pTabList, p->iTable))!=0
         1609  +    ){
  1595   1610         char *zCol;
  1596   1611         int iCol = p->iColumn;
  1597         -      for(j=0; ALWAYS(j<pTabList->nSrc); j++){
  1598         -        if( pTabList->a[j].iCursor==p->iTable ) break;
  1599         -      }
  1600         -      assert( j<pTabList->nSrc );
  1601         -      pTab = pTabList->a[j].pTab;
  1602   1612         if( iCol<0 ) iCol = pTab->iPKey;
  1603   1613         assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
  1604   1614         if( iCol<0 ){
  1605   1615           zCol = "rowid";
  1606   1616         }else{
  1607   1617           zCol = pTab->aCol[iCol].zName;
  1608   1618         }
................................................................................
  3143   3153   ** a column in table number iTable with a copy of the iColumn-th
  3144   3154   ** entry in pEList.  (But leave references to the ROWID column 
  3145   3155   ** unchanged.)
  3146   3156   **
  3147   3157   ** This routine is part of the flattening procedure.  A subquery
  3148   3158   ** whose result set is defined by pEList appears as entry in the
  3149   3159   ** FROM clause of a SELECT such that the VDBE cursor assigned to that
  3150         -** FORM clause entry is iTable.  This routine make the necessary 
         3160  +** FORM clause entry is iTable.  This routine makes the necessary 
  3151   3161   ** changes to pExpr so that it refers directly to the source table
  3152   3162   ** of the subquery rather the result set of the subquery.
  3153   3163   */
  3154   3164   static Expr *substExpr(
  3155   3165     Parse *pParse,      /* Report errors here */
  3156   3166     Expr *pExpr,        /* Expr in which substitution occurs */
  3157   3167     int iTable,         /* Table to be substituted */

Changes to src/sqlite.h.in.

  3697   3697   ** ^The sqlite3_value object returned by
  3698   3698   ** [sqlite3_column_value()] is unprotected.
  3699   3699   ** Unprotected sqlite3_value objects may only be used with
  3700   3700   ** [sqlite3_result_value()] and [sqlite3_bind_value()].
  3701   3701   ** The [sqlite3_value_blob | sqlite3_value_type()] family of
  3702   3702   ** interfaces require protected sqlite3_value objects.
  3703   3703   */
  3704         -typedef struct Mem sqlite3_value;
         3704  +typedef struct sqlite3_value sqlite3_value;
  3705   3705   
  3706   3706   /*
  3707   3707   ** CAPI3REF: SQL Function Context Object
  3708   3708   **
  3709   3709   ** The context in which an SQL function executes is stored in an
  3710   3710   ** sqlite3_context object.  ^A pointer to an sqlite3_context object
  3711   3711   ** is always first parameter to [application-defined SQL functions].

Changes to src/sqliteInt.h.

  3324   3324       int n;                                     /* A counter */
  3325   3325       int iCur;                                  /* A cursor number */
  3326   3326       SrcList *pSrcList;                         /* FROM clause */
  3327   3327       struct SrcCount *pSrcCount;                /* Counting column references */
  3328   3328       struct CCurHint *pCCurHint;                /* Used by codeCursorHint() */
  3329   3329       int *aiCol;                                /* array of column indexes */
  3330   3330       struct IdxCover *pIdxCover;                /* Check for index coverage */
         3331  +    struct IdxExprTrans *pIdxTrans;            /* Convert indexed expr to column */
  3331   3332     } u;
  3332   3333   };
  3333   3334   
  3334   3335   /* Forward declarations */
  3335   3336   int sqlite3WalkExpr(Walker*, Expr*);
  3336   3337   int sqlite3WalkExprList(Walker*, ExprList*);
  3337   3338   int sqlite3WalkSelect(Walker*, Select*);

Changes to src/vdbe.h.

    26     26   */
    27     27   typedef struct Vdbe Vdbe;
    28     28   
    29     29   /*
    30     30   ** The names of the following types declared in vdbeInt.h are required
    31     31   ** for the VdbeOp definition.
    32     32   */
    33         -typedef struct Mem Mem;
           33  +typedef struct sqlite3_value Mem;
    34     34   typedef struct SubProgram SubProgram;
    35     35   
    36     36   /*
    37     37   ** A single instruction of the virtual machine has an opcode
    38     38   ** and as many as three operands.  The instruction is recorded
    39     39   ** as an instance of the following structure:
    40     40   */

Changes to src/vdbeInt.h.

   181    181   #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
   182    182   
   183    183   /*
   184    184   ** Internally, the vdbe manipulates nearly all SQL values as Mem
   185    185   ** structures. Each Mem struct may cache multiple representations (string,
   186    186   ** integer etc.) of the same value.
   187    187   */
   188         -struct Mem {
          188  +struct sqlite3_value {
   189    189     union MemValue {
   190    190       double r;           /* Real value used when MEM_Real is set in flags */
   191    191       i64 i;              /* Integer value used when MEM_Int is set in flags */
   192    192       int nZero;          /* Used when bit MEM_Zero is set in flags */
   193    193       FuncDef *pDef;      /* Used only when flags==MEM_Agg */
   194    194       RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
   195    195       VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */

Changes to src/vdbeaux.c.

   875    875   ** Free the space allocated for aOp and any p4 values allocated for the
   876    876   ** opcodes contained within. If aOp is not NULL it is assumed to contain 
   877    877   ** nOp entries. 
   878    878   */
   879    879   static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
   880    880     if( aOp ){
   881    881       Op *pOp;
   882         -    for(pOp=aOp; pOp<&aOp[nOp]; pOp++){
          882  +    for(pOp=&aOp[nOp-1]; pOp>=aOp; pOp--){
   883    883         if( pOp->p4type ) freeP4(db, pOp->p4type, pOp->p4.p);
   884    884   #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
   885    885         sqlite3DbFree(db, pOp->zComment);
   886    886   #endif     
   887    887       }
   888    888       sqlite3DbFreeNN(db, aOp);
   889    889     }

Changes to src/vdbemem.c.

   121    121     /* If the bPreserve flag is set to true, then the memory cell must already
   122    122     ** contain a valid string or blob value.  */
   123    123     assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) );
   124    124     testcase( bPreserve && pMem->z==0 );
   125    125   
   126    126     assert( pMem->szMalloc==0
   127    127          || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
   128         -  if( pMem->szMalloc<n ){
   129         -    if( n<32 ) n = 32;
   130         -    if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){
   131         -      pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
   132         -      bPreserve = 0;
   133         -    }else{
   134         -      if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
   135         -      pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
   136         -    }
   137         -    if( pMem->zMalloc==0 ){
   138         -      sqlite3VdbeMemSetNull(pMem);
   139         -      pMem->z = 0;
   140         -      pMem->szMalloc = 0;
   141         -      return SQLITE_NOMEM_BKPT;
   142         -    }else{
   143         -      pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
   144         -    }
          128  +  if( n<32 ) n = 32;
          129  +  if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){
          130  +    pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
          131  +    bPreserve = 0;
          132  +  }else{
          133  +    if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
          134  +    pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
          135  +  }
          136  +  if( pMem->zMalloc==0 ){
          137  +    sqlite3VdbeMemSetNull(pMem);
          138  +    pMem->z = 0;
          139  +    pMem->szMalloc = 0;
          140  +    return SQLITE_NOMEM_BKPT;
          141  +  }else{
          142  +    pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
   145    143     }
   146    144   
   147         -  if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){
          145  +  if( bPreserve && pMem->z && ALWAYS(pMem->z!=pMem->zMalloc) ){
   148    146       memcpy(pMem->zMalloc, pMem->z, pMem->n);
   149    147     }
   150    148     if( (pMem->flags&MEM_Dyn)!=0 ){
   151    149       assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC );
   152    150       pMem->xDel((void *)(pMem->z));
   153    151     }
   154    152   

Changes to src/where.c.

  4638   4638       sqlite3DbFree(db, pWInfo);
  4639   4639       pWInfo = 0;
  4640   4640       goto whereBeginError;
  4641   4641     }
  4642   4642     pWInfo->pParse = pParse;
  4643   4643     pWInfo->pTabList = pTabList;
  4644   4644     pWInfo->pOrderBy = pOrderBy;
         4645  +  pWInfo->pWhere = pWhere;
  4645   4646     pWInfo->pResultSet = pResultSet;
  4646   4647     pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
  4647   4648     pWInfo->nLevel = nTabList;
  4648   4649     pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
  4649   4650     pWInfo->wctrlFlags = wctrlFlags;
  4650   4651     pWInfo->iLimit = iAuxArg;
  4651   4652     pWInfo->savedNQueryLoop = pParse->nQueryLoop;

Changes to src/whereInt.h.

   413    413   ** planner.
   414    414   */
   415    415   struct WhereInfo {
   416    416     Parse *pParse;            /* Parsing and code generating context */
   417    417     SrcList *pTabList;        /* List of tables in the join */
   418    418     ExprList *pOrderBy;       /* The ORDER BY clause or NULL */
   419    419     ExprList *pResultSet;     /* Result set of the query */
          420  +  Expr *pWhere;             /* The complete WHERE clause */
   420    421     LogEst iLimit;            /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
   421    422     int aiCurOnePass[2];      /* OP_OpenWrite cursors for the ONEPASS opt */
   422    423     int iContinue;            /* Jump here to continue with next record */
   423    424     int iBreak;               /* Jump here to break out of the loop */
   424    425     int savedNQueryLoop;      /* pParse->nQueryLoop outside the WHERE loop */
   425    426     u16 wctrlFlags;           /* Flags originally passed to sqlite3WhereBegin() */
   426    427     u8 nLevel;                /* Number of nested loop */

Changes to src/wherecode.c.

  1034   1034         }
  1035   1035       }
  1036   1036     }else{
  1037   1037       assert( nReg==1 );
  1038   1038       sqlite3ExprCode(pParse, p, iReg);
  1039   1039     }
  1040   1040   }
         1041  +
         1042  +/* An instance of the IdxExprTrans object carries information about a
         1043  +** mapping from an expression on table columns into a column in an index
         1044  +** down through the Walker.
         1045  +*/
         1046  +typedef struct IdxExprTrans {
         1047  +  Expr *pIdxExpr;    /* The index expression */
         1048  +  int iTabCur;       /* The cursor of the corresponding table */
         1049  +  int iIdxCur;       /* The cursor for the index */
         1050  +  int iIdxCol;       /* The column for the index */
         1051  +} IdxExprTrans;
         1052  +
         1053  +/* The walker node callback used to transform matching expressions into
         1054  +** a reference to an index column for an index on an expression.
         1055  +**
         1056  +** If pExpr matches, then transform it into a reference to the index column
         1057  +** that contains the value of pExpr.
         1058  +*/
         1059  +static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
         1060  +  IdxExprTrans *pX = p->u.pIdxTrans;
         1061  +  if( sqlite3ExprCompare(pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
         1062  +    pExpr->op = TK_COLUMN;
         1063  +    pExpr->iTable = pX->iIdxCur;
         1064  +    pExpr->iColumn = pX->iIdxCol;
         1065  +    pExpr->pTab = 0;
         1066  +    return WRC_Prune;
         1067  +  }else{
         1068  +    return WRC_Continue;
         1069  +  }
         1070  +}
         1071  +
         1072  +/*
         1073  +** For an indexes on expression X, locate every instance of expression X in pExpr
         1074  +** and change that subexpression into a reference to the appropriate column of
         1075  +** the index.
         1076  +*/
         1077  +static void whereIndexExprTrans(
         1078  +  Index *pIdx,      /* The Index */
         1079  +  int iTabCur,      /* Cursor of the table that is being indexed */
         1080  +  int iIdxCur,      /* Cursor of the index itself */
         1081  +  WhereInfo *pWInfo /* Transform expressions in this WHERE clause */
         1082  +){
         1083  +  int iIdxCol;               /* Column number of the index */
         1084  +  ExprList *aColExpr;        /* Expressions that are indexed */
         1085  +  Walker w;
         1086  +  IdxExprTrans x;
         1087  +  aColExpr = pIdx->aColExpr;
         1088  +  if( aColExpr==0 ) return;  /* Not an index on expressions */
         1089  +  memset(&w, 0, sizeof(w));
         1090  +  w.xExprCallback = whereIndexExprTransNode;
         1091  +  w.u.pIdxTrans = &x;
         1092  +  x.iTabCur = iTabCur;
         1093  +  x.iIdxCur = iIdxCur;
         1094  +  for(iIdxCol=0; iIdxCol<aColExpr->nExpr; iIdxCol++){
         1095  +    if( pIdx->aiColumn[iIdxCol]!=XN_EXPR ) continue;
         1096  +    assert( aColExpr->a[iIdxCol].pExpr!=0 );
         1097  +    x.iIdxCol = iIdxCol;
         1098  +    x.pIdxExpr = aColExpr->a[iIdxCol].pExpr;
         1099  +    sqlite3WalkExpr(&w, pWInfo->pWhere);
         1100  +    sqlite3WalkExprList(&w, pWInfo->pOrderBy);
         1101  +    sqlite3WalkExprList(&w, pWInfo->pResultSet);
         1102  +  }
         1103  +}
  1041   1104   
  1042   1105   /*
  1043   1106   ** Generate code for the start of the iLevel-th loop in the WHERE clause
  1044   1107   ** implementation described by pWInfo.
  1045   1108   */
  1046   1109   Bitmask sqlite3WhereCodeOneLoopStart(
  1047   1110     WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
................................................................................
  1615   1678         for(j=0; j<pPk->nKeyCol; j++){
  1616   1679           k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
  1617   1680           sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j);
  1618   1681         }
  1619   1682         sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont,
  1620   1683                              iRowidReg, pPk->nKeyCol); VdbeCoverage(v);
  1621   1684       }
         1685  +
         1686  +    /* If pIdx is an index on one or more expressions, then look through
         1687  +    ** all the expressions in pWInfo and try to transform matching expressions
         1688  +    ** into reference to index columns.
         1689  +    */
         1690  +    whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
         1691  +
  1622   1692   
  1623   1693       /* Record the instruction used to terminate the loop. */
  1624   1694       if( pLoop->wsFlags & WHERE_ONEROW ){
  1625   1695         pLevel->op = OP_Noop;
  1626   1696       }else if( bRev ){
  1627   1697         pLevel->op = OP_Prev;
  1628   1698       }else{

Changes to src/whereexpr.c.

   826    826     return mask;
   827    827   }
   828    828   
   829    829   /*
   830    830   ** Expression pExpr is one operand of a comparison operator that might
   831    831   ** be useful for indexing.  This routine checks to see if pExpr appears
   832    832   ** in any index.  Return TRUE (1) if pExpr is an indexed term and return
   833         -** FALSE (0) if not.  If TRUE is returned, also set *piCur to the cursor
   834         -** number of the table that is indexed and *piColumn to the column number
          833  +** FALSE (0) if not.  If TRUE is returned, also set aiCurCol[0] to the cursor
          834  +** number of the table that is indexed and aiCurCol[1] to the column number
   835    835   ** of the column that is indexed, or XN_EXPR (-2) if an expression is being
   836    836   ** indexed.
   837    837   **
   838    838   ** If pExpr is a TK_COLUMN column reference, then this routine always returns
   839    839   ** true even if that particular column is not indexed, because the column
   840    840   ** might be added to an automatic index later.
   841    841   */
   842         -static int exprMightBeIndexed(
          842  +static SQLITE_NOINLINE int exprMightBeIndexed2(
   843    843     SrcList *pFrom,        /* The FROM clause */
   844         -  int op,                /* The specific comparison operator */
   845    844     Bitmask mPrereq,       /* Bitmask of FROM clause terms referenced by pExpr */
   846         -  Expr *pExpr,           /* An operand of a comparison operator */
   847         -  int *piCur,            /* Write the referenced table cursor number here */
   848         -  int *piColumn          /* Write the referenced table column number here */
          845  +  int *aiCurCol,         /* Write the referenced table cursor and column here */
          846  +  Expr *pExpr            /* An operand of a comparison operator */
   849    847   ){
   850    848     Index *pIdx;
   851    849     int i;
   852    850     int iCur;
   853         -
          851  +  for(i=0; mPrereq>1; i++, mPrereq>>=1){}
          852  +  iCur = pFrom->a[i].iCursor;
          853  +  for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
          854  +    if( pIdx->aColExpr==0 ) continue;
          855  +    for(i=0; i<pIdx->nKeyCol; i++){
          856  +      if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
          857  +      if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
          858  +        aiCurCol[0] = iCur;
          859  +        aiCurCol[1] = XN_EXPR;
          860  +        return 1;
          861  +      }
          862  +    }
          863  +  }
          864  +  return 0;
          865  +}
          866  +static int exprMightBeIndexed(
          867  +  SrcList *pFrom,        /* The FROM clause */
          868  +  Bitmask mPrereq,       /* Bitmask of FROM clause terms referenced by pExpr */
          869  +  int *aiCurCol,         /* Write the referenced table cursor & column here */
          870  +  Expr *pExpr,           /* An operand of a comparison operator */
          871  +  int op                 /* The specific comparison operator */
          872  +){
   854    873     /* If this expression is a vector to the left or right of a 
   855    874     ** inequality constraint (>, <, >= or <=), perform the processing 
   856    875     ** on the first element of the vector.  */
   857    876     assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE );
   858    877     assert( TK_IS<TK_GE && TK_ISNULL<TK_GE && TK_IN<TK_GE );
   859    878     assert( op<=TK_GE );
   860    879     if( pExpr->op==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){
   861    880       pExpr = pExpr->x.pList->a[0].pExpr;
   862    881     }
   863    882   
   864    883     if( pExpr->op==TK_COLUMN ){
   865         -    *piCur = pExpr->iTable;
   866         -    *piColumn = pExpr->iColumn;
          884  +    aiCurCol[0] = pExpr->iTable;
          885  +    aiCurCol[1] = pExpr->iColumn;
   867    886       return 1;
   868    887     }
   869    888     if( mPrereq==0 ) return 0;                 /* No table references */
   870    889     if( (mPrereq&(mPrereq-1))!=0 ) return 0;   /* Refs more than one table */
   871         -  for(i=0; mPrereq>1; i++, mPrereq>>=1){}
   872         -  iCur = pFrom->a[i].iCursor;
   873         -  for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
   874         -    if( pIdx->aColExpr==0 ) continue;
   875         -    for(i=0; i<pIdx->nKeyCol; i++){
   876         -      if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
   877         -      if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
   878         -        *piCur = iCur;
   879         -        *piColumn = XN_EXPR;
   880         -        return 1;
   881         -      }
   882         -    }
   883         -  }
   884         -  return 0;
          890  +  return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr);
   885    891   }
   886    892   
   887    893   /*
   888    894   ** The input to this routine is an WhereTerm structure with only the
   889    895   ** "pExpr" field filled in.  The job of this routine is to analyze the
   890    896   ** subexpression and populate all the other fields of the WhereTerm
   891    897   ** structure.
................................................................................
   957    963       }
   958    964     }
   959    965     pTerm->prereqAll = prereqAll;
   960    966     pTerm->leftCursor = -1;
   961    967     pTerm->iParent = -1;
   962    968     pTerm->eOperator = 0;
   963    969     if( allowedOp(op) ){
   964         -    int iCur, iColumn;
          970  +    int aiCurCol[2];
   965    971       Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
   966    972       Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
   967    973       u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
   968    974   
   969    975       if( pTerm->iField>0 ){
   970    976         assert( op==TK_IN );
   971    977         assert( pLeft->op==TK_VECTOR );
   972    978         pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr;
   973    979       }
   974    980   
   975         -    if( exprMightBeIndexed(pSrc, op, prereqLeft, pLeft, &iCur, &iColumn) ){
   976         -      pTerm->leftCursor = iCur;
   977         -      pTerm->u.leftColumn = iColumn;
          981  +    if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){
          982  +      pTerm->leftCursor = aiCurCol[0];
          983  +      pTerm->u.leftColumn = aiCurCol[1];
   978    984         pTerm->eOperator = operatorMask(op) & opMask;
   979    985       }
   980    986       if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
   981    987       if( pRight 
   982         -     && exprMightBeIndexed(pSrc, op, pTerm->prereqRight, pRight, &iCur,&iColumn)
          988  +     && exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op)
   983    989       ){
   984    990         WhereTerm *pNew;
   985    991         Expr *pDup;
   986    992         u16 eExtraOp = 0;        /* Extra bits for pNew->eOperator */
   987    993         assert( pTerm->iField==0 );
   988    994         if( pTerm->leftCursor>=0 ){
   989    995           int idxNew;
................................................................................
  1005   1011             eExtraOp = WO_EQUIV;
  1006   1012           }
  1007   1013         }else{
  1008   1014           pDup = pExpr;
  1009   1015           pNew = pTerm;
  1010   1016         }
  1011   1017         exprCommute(pParse, pDup);
  1012         -      pNew->leftCursor = iCur;
  1013         -      pNew->u.leftColumn = iColumn;
         1018  +      pNew->leftCursor = aiCurCol[0];
         1019  +      pNew->u.leftColumn = aiCurCol[1];
  1014   1020         testcase( (prereqLeft | extraRight) != prereqLeft );
  1015   1021         pNew->prereqRight = prereqLeft | extraRight;
  1016   1022         pNew->prereqAll = prereqAll;
  1017   1023         pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask;
  1018   1024       }
  1019   1025     }
  1020   1026   

Added test/indexexpr2.test.

            1  +# 2017 April 11
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library.
           12  +#
           13  +
           14  +set testdir [file dirname $argv0]
           15  +source $testdir/tester.tcl
           16  +set testprefix indexexpr2
           17  +
           18  +do_execsql_test 1 {
           19  +  CREATE TABLE t1(a, b);
           20  +  INSERT INTO t1 VALUES(1, 'one');
           21  +  INSERT INTO t1 VALUES(2, 'two');
           22  +  INSERT INTO t1 VALUES(3, 'three');
           23  +
           24  +  CREATE INDEX i1 ON t1(b || 'x');
           25  +}
           26  +
           27  +do_execsql_test 1.1 {
           28  +  SELECT 'TWOX' == (b || 'x') FROM t1 WHERE (b || 'x')>'onex'
           29  +} {0 0}
           30  +
           31  +do_execsql_test 1.2 {
           32  +  SELECT 'TWOX' == (b || 'x') COLLATE nocase  FROM t1 WHERE (b || 'x')>'onex'
           33  +} {0 1}
           34  +
           35  +finish_test
           36  +

Changes to test/json102.test.

   314    314   do_execsql_test json102-1406 { SELECT json_valid('{"x":-0.1}') } 1
   315    315   do_execsql_test json102-1407 { SELECT json_valid('{"x":0.0000}') } 1
   316    316   do_execsql_test json102-1408 { SELECT json_valid('{"x":-0.0000}') } 1
   317    317   do_execsql_test json102-1409 { SELECT json_valid('{"x":01.5}') } 0
   318    318   do_execsql_test json102-1410 { SELECT json_valid('{"x":-01.5}') } 0
   319    319   do_execsql_test json102-1411 { SELECT json_valid('{"x":00}') } 0
   320    320   do_execsql_test json102-1412 { SELECT json_valid('{"x":-00}') } 0
          321  +
          322  +#------------------------------------------------------------------------
          323  +# 2017-04-10 ticket 6c9b5514077fed34551f98e64c09a10dc2fc8e16
          324  +# JSON extension accepts strings containing control characters.
          325  +#
          326  +# The JSON spec requires that all control characters be escaped.
          327  +#
          328  +do_execsql_test json102-1500 {
          329  +  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<0x20)
          330  +  SELECT x FROM c WHERE json_valid(printf('{"a":"x%sz"}', char(x))) ORDER BY x;
          331  +} {32}
          332  +
          333  +# All control characters are escaped
          334  +#
          335  +do_execsql_test json102-1501 {
          336  +  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<0x1f)
          337  +  SELECT sum(json_valid(json_quote('a'||char(x)||'z'))) FROM c ORDER BY x;
          338  +} {31}
   321    339   
   322    340   finish_test