/ Check-in [b0cc6be4]
Login

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

Overview
Comment:Allow ROWID values in indexed vector comparisons.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | rowvalue
Files: files | file ages | folders
SHA1: b0cc6be4eb81f21b11796e1f14d4412bf21dea6e
User & Date: drh 2016-08-26 13:19:49
Context
2016-08-26
17:54
Fix a problem with affinity changes and vector range comparisons. check-in: b34413ac user: dan tags: rowvalue
13:19
Allow ROWID values in indexed vector comparisons. check-in: b0cc6be4 user: drh tags: rowvalue
03:42
Comment improvements. Put ALWAYS and NEVER macros on three unreachable branches. check-in: 39761700 user: drh tags: rowvalue
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/expr.c.

    14     14   */
    15     15   #include "sqliteInt.h"
    16     16   
    17     17   /* Forward declarations */
    18     18   static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int);
    19     19   static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree);
    20     20   
           21  +/*
           22  +** Return the affinity character for a single column of a table.
           23  +*/
           24  +char sqlite3TableColumnAffinity(Table *pTab, int iCol){
           25  +  assert( iCol<pTab->nCol );
           26  +  return iCol>=0 ? pTab->aCol[iCol].affinity : SQLITE_AFF_INTEGER;
           27  +}
    21     28   
    22     29   /*
    23     30   ** Return the 'affinity' of the expression pExpr if any.
    24     31   **
    25     32   ** If pExpr is a column, a reference to a column via an 'AS' alias,
    26     33   ** or a sub-select with a column as the return value, then the 
    27     34   ** affinity of that column is returned. Otherwise, 0x00 is returned,
................................................................................
    48     55   #ifndef SQLITE_OMIT_CAST
    49     56     if( op==TK_CAST ){
    50     57       assert( !ExprHasProperty(pExpr, EP_IntValue) );
    51     58       return sqlite3AffinityType(pExpr->u.zToken, 0);
    52     59     }
    53     60   #endif
    54     61     if( op==TK_AGG_COLUMN || op==TK_COLUMN ){
    55         -    int j = pExpr->iColumn;
    56         -    assert( pExpr->pTab!=0 );
    57         -    if( j<0 ) return SQLITE_AFF_INTEGER;
    58         -    assert( pExpr->pTab && j<pExpr->pTab->nCol );
    59         -    return pExpr->pTab->aCol[j].affinity;
           62  +    return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
    60     63     }
    61     64     return pExpr->affinity;
    62     65   }
    63     66   
    64     67   /*
    65     68   ** Set the collating sequence for expression pExpr to be the collating
    66     69   ** sequence named by pToken.   Return a pointer to a new Expr node that
................................................................................
  2169   2172         /* Check that the affinity that will be used to perform each 
  2170   2173         ** comparison is the same as the affinity of each column in table
  2171   2174         ** on the RHS of the IN operator.  If it not, it is not possible to
  2172   2175         ** use any index of the RHS table.  */
  2173   2176         for(i=0; i<nExpr && affinity_ok; i++){
  2174   2177           Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
  2175   2178           int iCol = pEList->a[i].pExpr->iColumn;
  2176         -        char idxaff = pTab->aCol[iCol].affinity;  /* RHS table affinity */
         2179  +        char idxaff = sqlite3TableColumnAffinity(pTab,iCol); /* RHS table */
  2177   2180           char cmpaff = sqlite3CompareAffinity(pLhs, idxaff);
  2178   2181           testcase( cmpaff==SQLITE_AFF_BLOB );
  2179   2182           testcase( cmpaff==SQLITE_AFF_TEXT );
  2180   2183           switch( cmpaff ){
  2181   2184             case SQLITE_AFF_BLOB:
  2182   2185               break;
  2183   2186             case SQLITE_AFF_TEXT:
................................................................................
  2204   2207   
  2205   2208           for(i=0; i<nExpr; i++){
  2206   2209             Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
  2207   2210             Expr *pRhs = pEList->a[i].pExpr;
  2208   2211             CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
  2209   2212             int j;
  2210   2213   
  2211         -          assert( pReq || pParse->nErr );
  2212   2214             if( pReq==0 ) break;
  2213   2215   
  2214   2216             for(j=0; j<nExpr; j++){
  2215   2217               if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
  2216   2218               assert( pIdx->azColl[j] );
  2217   2219               if( sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ) continue;
  2218   2220               break;

Changes to src/sqliteInt.h.

  3879   3879   #define putVarint    sqlite3PutVarint
  3880   3880   
  3881   3881   
  3882   3882   const char *sqlite3IndexAffinityStr(sqlite3*, Index*);
  3883   3883   void sqlite3TableAffinity(Vdbe*, Table*, int);
  3884   3884   char sqlite3CompareAffinity(Expr *pExpr, char aff2);
  3885   3885   int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
         3886  +char sqlite3TableColumnAffinity(Table*,int);
  3886   3887   char sqlite3ExprAffinity(Expr *pExpr);
  3887   3888   int sqlite3Atoi64(const char*, i64*, int, u8);
  3888   3889   int sqlite3DecOrHexToI64(const char*, i64*);
  3889   3890   void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
  3890   3891   void sqlite3Error(sqlite3*,int);
  3891   3892   void sqlite3SystemError(sqlite3*,int);
  3892   3893   void *sqlite3HexToBlob(sqlite3*, const char *z, int n);

Changes to src/where.c.

  2257   2257        || pLhs->iColumn!=pIdx->aiColumn[i+nEq] 
  2258   2258        || pIdx->aSortOrder[i+nEq]!=pIdx->aSortOrder[nEq]
  2259   2259       ){
  2260   2260         break;
  2261   2261       }
  2262   2262   
  2263   2263       aff = sqlite3CompareAffinity(pRhs, sqlite3ExprAffinity(pLhs));
  2264         -    idxaff = pIdx->pTable->aCol[pLhs->iColumn].affinity;
         2264  +    idxaff = sqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn);
  2265   2265       if( aff!=idxaff ) break;
  2266   2266   
  2267   2267       pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
  2268         -    if( NEVER(pColl==0) ) break;
         2268  +    if( pColl==0 ) break;
  2269   2269       if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break;
  2270   2270     }
  2271   2271     return i;
  2272   2272   }
  2273   2273   
  2274   2274   /*
  2275   2275   ** Adjust the cost C by the costMult facter T.  This only occurs if