/ Check-in [3b68aa25]
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:Correctly handle column names and string constants in parentheses. Fix for ticket #179. (CVS 770)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3b68aa25c451b7c09ece457ac2b70a9a5d93508a
User & Date: drh 2002-10-22 23:38:04
Context
2002-10-27
19:35
Minimal support for oracle8 outer join syntax. (CVS 771) check-in: 31df3690 user: drh tags: trunk
2002-10-22
23:38
Correctly handle column names and string constants in parentheses. Fix for ticket #179. (CVS 770) check-in: 3b68aa25 user: drh tags: trunk
15:04
Take care to track ephemeral strings in the VDBE and make copies of ephemeral strings that need to be preserved. Ticket #177. (CVS 769) check-in: 562da534 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/expr.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains routines used for analyzing expressions and
    13     13   ** for generating VDBE code that evaluates expressions in SQLite.
    14     14   **
    15         -** $Id: expr.c,v 1.81 2002/09/08 00:04:52 drh Exp $
           15  +** $Id: expr.c,v 1.82 2002/10/22 23:38:04 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   #include <ctype.h>
    19     19   
    20     20   /*
    21     21   ** Construct a new expression node and return a pointer to it.  Memory
    22     22   ** for this node is obtained from sqliteMalloc().  The calling function
................................................................................
    32     32     }
    33     33     pNew->op = op;
    34     34     pNew->pLeft = pLeft;
    35     35     pNew->pRight = pRight;
    36     36     if( pToken ){
    37     37       assert( pToken->dyn==0 );
    38     38       pNew->token = *pToken;
    39         -    pNew->token.base = 1;
    40         -  }else if( pLeft && pRight ){
    41         -    sqliteExprSpan(pNew, &pLeft->token, &pRight->token);
           39  +    pNew->span = *pToken;
    42     40     }else{
    43     41       pNew->token.dyn = 0;
    44         -    pNew->token.base = 1;
    45     42       pNew->token.z = 0;
    46     43       pNew->token.n = 0;
           44  +    if( pLeft && pRight ){
           45  +      sqliteExprSpan(pNew, &pLeft->span, &pRight->span);
           46  +    }else{
           47  +      pNew->span = pNew->token;
           48  +    }
    47     49     }
    48     50     return pNew;
    49     51   }
    50     52   
    51     53   /*
    52         -** Set the Expr.token field of the given expression to span all
           54  +** Set the Expr.span field of the given expression to span all
    53     55   ** text between the two given tokens.
    54     56   */
    55     57   void sqliteExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
    56         -  if( pExpr ){
    57         -    assert( pExpr->token.dyn==0 );
           58  +  if( pExpr && pRight && pRight->z && pLeft && pLeft->z ){
    58     59       if( pLeft->dyn==0 && pRight->dyn==0 ){
    59         -      pExpr->token.z = pLeft->z;
    60         -      pExpr->token.n = pRight->n + Addr(pRight->z) - Addr(pLeft->z);
    61         -      pExpr->token.base = 0;
           60  +      pExpr->span.z = pLeft->z;
           61  +      pExpr->span.n = pRight->n + Addr(pRight->z) - Addr(pLeft->z);
    62     62       }else{
    63         -      pExpr->token.z = 0;
    64         -      pExpr->token.n = 0;
    65         -      pExpr->token.dyn = 0;
    66         -      pExpr->token.base = 0;
           63  +      pExpr->span.z = 0;
           64  +      pExpr->span.n = 0;
           65  +      pExpr->span.dyn = 0;
    67     66       }
    68     67     }
    69     68   }
    70     69   
    71     70   /*
    72     71   ** Construct a new expression node for a function with multiple
    73     72   ** arguments.
................................................................................
    77     76     pNew = sqliteMalloc( sizeof(Expr) );
    78     77     if( pNew==0 ){
    79     78       sqliteExprListDelete(pList);
    80     79       return 0;
    81     80     }
    82     81     pNew->op = TK_FUNCTION;
    83     82     pNew->pList = pList;
    84         -
    85         -  /* Expr.token.n is the length of the entire function
    86         -  ** call, including the function arguments.  The parser
    87         -  ** will extend token.n to cover the either length of the string.
    88         -  ** Expr.nFuncName is the length of just the function name.
    89         -  */
    90     83     pNew->token.dyn = 0;
    91         -  pNew->token.base = 1;
    92     84     if( pToken ){
    93     85       assert( pToken->dyn==0 );
    94     86       pNew->token = *pToken;
    95         -    pNew->nFuncName = pToken->n>255 ? 255 : pToken->n;
    96     87     }else{
    97     88       pNew->token.z = 0;
    98     89       pNew->token.n = 0;
    99     90     }
           91  +  pNew->span = pNew->token;
   100     92     return pNew;
   101     93   }
   102     94   
   103     95   /*
   104     96   ** Recursively delete an expression tree.
   105     97   */
   106     98   void sqliteExprDelete(Expr *p){
   107     99     if( p==0 ) return;
          100  +  if( p->span.dyn && p->span.z ) sqliteFree((char*)p->span.z);
   108    101     if( p->token.dyn && p->token.z ) sqliteFree((char*)p->token.z);
   109    102     if( p->pLeft ) sqliteExprDelete(p->pLeft);
   110    103     if( p->pRight ) sqliteExprDelete(p->pRight);
   111    104     if( p->pList ) sqliteExprListDelete(p->pList);
   112    105     if( p->pSelect ) sqliteSelectDelete(p->pSelect);
   113    106     sqliteFree(p);
   114    107   }
................................................................................
   128    121   */
   129    122   Expr *sqliteExprDup(Expr *p){
   130    123     Expr *pNew;
   131    124     if( p==0 ) return 0;
   132    125     pNew = sqliteMalloc( sizeof(*p) );
   133    126     if( pNew==0 ) return 0;
   134    127     memcpy(pNew, p, sizeof(*pNew));
   135         -  /* Only make a copy of the token if it is a base token (meaning that
   136         -  ** it covers a single term of an expression - not two or more terms)
   137         -  ** or if it is already dynamically allocated.  So, for example, in
   138         -  ** a complex expression like "a+b+c", the token "b" would be duplicated
   139         -  ** but "a+b" would not be. */
   140         -  if( p->token.z!=0 && (p->token.base || p->token.dyn) ){
          128  +  if( p->token.z!=0 ){
   141    129       pNew->token.z = sqliteStrDup(p->token.z);
   142    130       pNew->token.dyn = 1;
   143    131     }else{
   144    132       pNew->token.z = 0;
   145    133       pNew->token.n = 0;
   146    134       pNew->token.dyn = 0;
   147    135     }
          136  +  pNew->span.z = 0;
          137  +  pNew->span.n = 0;
          138  +  pNew->span.dyn = 0;
   148    139     pNew->pLeft = sqliteExprDup(p->pLeft);
   149    140     pNew->pRight = sqliteExprDup(p->pRight);
   150    141     pNew->pList = sqliteExprListDup(p->pList);
   151    142     pNew->pSelect = sqliteSelectDup(p->pSelect);
   152    143     return pNew;
   153    144   }
   154    145   void sqliteTokenCopy(Token *pTo, Token *pFrom){
   155    146     if( pTo->dyn ) sqliteFree((char*)pTo->z);
   156         -  pTo->base = pFrom->base;
   157    147     if( pFrom->z ){
   158    148       pTo->n = pFrom->n;
   159    149       pTo->z = sqliteStrNDup(pFrom->z, pFrom->n);
   160    150       pTo->dyn = 1;
   161    151     }else{
   162    152       pTo->n = 0;
   163    153       pTo->z = 0;
................................................................................
   172    162     if( pNew==0 ) return 0;
   173    163     pNew->nExpr = p->nExpr;
   174    164     pNew->a = sqliteMalloc( p->nExpr*sizeof(p->a[0]) );
   175    165     if( pNew->a==0 ) return 0;
   176    166     for(i=0; i<p->nExpr; i++){
   177    167       Expr *pNewExpr, *pOldExpr;
   178    168       pNew->a[i].pExpr = pNewExpr = sqliteExprDup(pOldExpr = p->a[i].pExpr);
   179         -    if( pOldExpr->token.z!=0 && pNewExpr && pNewExpr->token.z==0 ){
   180         -      /* Always make a copy of the token for top-level expressions in the
          169  +    if( pOldExpr->span.z!=0 && pNewExpr ){
          170  +      /* Always make a copy of the span for top-level expressions in the
   181    171         ** expression list.  The logic in SELECT processing that determines
   182    172         ** the names of columns in the result set needs this information */
   183         -      sqliteTokenCopy(&pNew->a[i].pExpr->token, &p->a[i].pExpr->token);
          173  +      sqliteTokenCopy(&pNewExpr->span, &pOldExpr->span);
   184    174       }
          175  +    assert( pNewExpr==0 || pNewExpr->span.z!=0 || pOldExpr->span.z==0 );
   185    176       pNew->a[i].zName = sqliteStrDup(p->a[i].zName);
   186    177       pNew->a[i].sortOrder = p->a[i].sortOrder;
   187    178       pNew->a[i].isAgg = p->a[i].isAgg;
   188    179       pNew->a[i].done = 0;
   189    180     }
   190    181     return pNew;
   191    182   }
................................................................................
   710    701   ** This routine makes *pzName point to the name of the function and 
   711    702   ** *pnName hold the number of characters in the function name.
   712    703   */
   713    704   static void getFunctionName(Expr *pExpr, const char **pzName, int *pnName){
   714    705     switch( pExpr->op ){
   715    706       case TK_FUNCTION: {
   716    707         *pzName = pExpr->token.z;
   717         -      *pnName = pExpr->nFuncName;
          708  +      *pnName = pExpr->token.n;
   718    709         break;
   719    710       }
   720    711       case TK_LIKE: {
   721    712         *pzName = "like";
   722    713         *pnName = 4;
   723    714         break;
   724    715       }
................................................................................
  1447   1438       }
  1448   1439     }else if( pB->pList ){
  1449   1440       return 0;
  1450   1441     }
  1451   1442     if( pA->pSelect || pB->pSelect ) return 0;
  1452   1443     if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0;
  1453   1444     if( pA->token.z ){
  1454         -    int n;
  1455   1445       if( pB->token.z==0 ) return 0;
  1456         -    if( pA->op==TK_FUNCTION || pA->op==TK_AGG_FUNCTION ){
  1457         -      n = pA->nFuncName;
  1458         -      if( pB->nFuncName!=n ) return 0;
  1459         -    }else{
  1460         -      n = pA->token.n;
  1461         -      if( pB->token.n!=n ) return 0;
  1462         -    }
  1463         -    if( sqliteStrNICmp(pA->token.z, pB->token.z, n)!=0 ) return 0;
         1446  +    if( pB->token.n!=pA->token.n ) return 0;
         1447  +    if( sqliteStrNICmp(pA->token.z, pB->token.z, pB->token.n)!=0 ) return 0;
  1464   1448     }
  1465   1449     return 1;
  1466   1450   }
  1467   1451   
  1468   1452   /*
  1469   1453   ** Add a new element to the pParse->aAgg[] array and return its index.
  1470   1454   */
................................................................................
  1527   1511         }
  1528   1512         if( i>=pParse->nAgg ){
  1529   1513           i = appendAggInfo(pParse);
  1530   1514           if( i<0 ) return 1;
  1531   1515           pParse->aAgg[i].isAgg = 1;
  1532   1516           pParse->aAgg[i].pExpr = pExpr;
  1533   1517           pParse->aAgg[i].pFunc = sqliteFindFunction(pParse->db,
  1534         -             pExpr->token.z, pExpr->nFuncName,
         1518  +             pExpr->token.z, pExpr->token.n,
  1535   1519                pExpr->pList ? pExpr->pList->nExpr : 0, 0);
  1536   1520         }
  1537   1521         pExpr->iAgg = i;
  1538   1522         break;
  1539   1523       }
  1540   1524       default: {
  1541   1525         if( pExpr->pLeft ){

Changes to src/parse.y.

    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains SQLite's grammar for SQL.  Process this file
    13     13   ** using the lemon parser generator to generate C code that runs
    14     14   ** the parser.  Lemon will also generate a header file containing
    15     15   ** numeric codes for all of the tokens.
    16     16   **
    17         -** @(#) $Id: parse.y,v 1.83 2002/08/31 18:53:07 drh Exp $
           17  +** @(#) $Id: parse.y,v 1.84 2002/10/22 23:38:04 drh Exp $
    18     18   */
    19     19   %token_prefix TK_
    20     20   %token_type {Token}
    21     21   %default_type {Token}
    22     22   %extra_argument {Parse *pParse}
    23     23   %syntax_error {
    24     24     sqliteSetString(&pParse->zErrMsg,"syntax error",0);
................................................................................
   499    499   %left STAR SLASH REM.
   500    500   %left CONCAT.
   501    501   %right UMINUS UPLUS BITNOT.
   502    502   
   503    503   %type expr {Expr*}
   504    504   %destructor expr {sqliteExprDelete($$);}
   505    505   
   506         -expr(A) ::= LP(B) expr(X) RP(E). {A = X; sqliteExprSpan(A,&B,&E);}
          506  +expr(A) ::= LP(B) expr(X) RP(E). {A = X; sqliteExprSpan(A,&B,&E); }
   507    507   expr(A) ::= NULL(X).             {A = sqliteExpr(TK_NULL, 0, 0, &X);}
   508    508   expr(A) ::= ID(X).               {A = sqliteExpr(TK_ID, 0, 0, &X);}
   509    509   expr(A) ::= JOIN_KW(X).          {A = sqliteExpr(TK_ID, 0, 0, &X);}
   510    510   expr(A) ::= nm(X) DOT nm(Y). {
   511    511     Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &X);
   512    512     Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &Y);
   513    513     A = sqliteExpr(TK_DOT, temp1, temp2, 0);
................................................................................
   514    514   }
   515    515   expr(A) ::= INTEGER(X).      {A = sqliteExpr(TK_INTEGER, 0, 0, &X);}
   516    516   expr(A) ::= FLOAT(X).        {A = sqliteExpr(TK_FLOAT, 0, 0, &X);}
   517    517   expr(A) ::= STRING(X).       {A = sqliteExpr(TK_STRING, 0, 0, &X);}
   518    518   expr(A) ::= ID(X) LP exprlist(Y) RP(E). {
   519    519     A = sqliteExprFunction(Y, &X);
   520    520     sqliteExprSpan(A,&X,&E);
   521         -  if( A ) A->token.base = 1;
   522    521   }
   523    522   expr(A) ::= ID(X) LP STAR RP(E). {
   524    523     A = sqliteExprFunction(0, &X);
   525    524     sqliteExprSpan(A,&X,&E);
   526         -  if( A ) A->token.base = 1;
   527    525   }
   528    526   expr(A) ::= expr(X) AND expr(Y).   {A = sqliteExpr(TK_AND, X, Y, 0);}
   529    527   expr(A) ::= expr(X) OR expr(Y).    {A = sqliteExpr(TK_OR, X, Y, 0);}
   530    528   expr(A) ::= expr(X) LT expr(Y).    {A = sqliteExpr(TK_LT, X, Y, 0);}
   531    529   expr(A) ::= expr(X) GT expr(Y).    {A = sqliteExpr(TK_GT, X, Y, 0);}
   532    530   expr(A) ::= expr(X) LE expr(Y).    {A = sqliteExpr(TK_LE, X, Y, 0);}
   533    531   expr(A) ::= expr(X) GE expr(Y).    {A = sqliteExpr(TK_GE, X, Y, 0);}
................................................................................
   538    536   expr(A) ::= expr(X) LSHIFT expr(Y). {A = sqliteExpr(TK_LSHIFT, X, Y, 0);}
   539    537   expr(A) ::= expr(X) RSHIFT expr(Y). {A = sqliteExpr(TK_RSHIFT, X, Y, 0);}
   540    538   expr(A) ::= expr(X) likeop(OP) expr(Y).  [LIKE]  {
   541    539     ExprList *pList = sqliteExprListAppend(0, Y, 0);
   542    540     pList = sqliteExprListAppend(pList, X, 0);
   543    541     A = sqliteExprFunction(pList, 0);
   544    542     if( A ) A->op = OP;
   545         -  sqliteExprSpan(A, &X->token, &Y->token);
          543  +  sqliteExprSpan(A, &X->span, &Y->span);
   546    544   }
   547    545   expr(A) ::= expr(X) NOT likeop(OP) expr(Y). [LIKE] {
   548    546     ExprList *pList = sqliteExprListAppend(0, Y, 0);
   549    547     pList = sqliteExprListAppend(pList, X, 0);
   550    548     A = sqliteExprFunction(pList, 0);
   551    549     if( A ) A->op = OP;
   552    550     A = sqliteExpr(TK_NOT, A, 0, 0);
   553         -  sqliteExprSpan(A,&X->token,&Y->token);
          551  +  sqliteExprSpan(A,&X->span,&Y->span);
   554    552   }
   555    553   %type likeop {int}
   556    554   likeop(A) ::= LIKE. {A = TK_LIKE;}
   557    555   likeop(A) ::= GLOB. {A = TK_GLOB;}
   558    556   expr(A) ::= expr(X) PLUS expr(Y).  {A = sqliteExpr(TK_PLUS, X, Y, 0);}
   559    557   expr(A) ::= expr(X) MINUS expr(Y). {A = sqliteExpr(TK_MINUS, X, Y, 0);}
   560    558   expr(A) ::= expr(X) STAR expr(Y).  {A = sqliteExpr(TK_STAR, X, Y, 0);}
   561    559   expr(A) ::= expr(X) SLASH expr(Y). {A = sqliteExpr(TK_SLASH, X, Y, 0);}
   562    560   expr(A) ::= expr(X) REM expr(Y).   {A = sqliteExpr(TK_REM, X, Y, 0);}
   563    561   expr(A) ::= expr(X) CONCAT expr(Y). {A = sqliteExpr(TK_CONCAT, X, Y, 0);}
   564    562   expr(A) ::= expr(X) ISNULL(E). {
   565    563     A = sqliteExpr(TK_ISNULL, X, 0, 0);
   566         -  sqliteExprSpan(A,&X->token,&E);
          564  +  sqliteExprSpan(A,&X->span,&E);
   567    565   }
   568    566   expr(A) ::= expr(X) IS NULL(E). {
   569    567     A = sqliteExpr(TK_ISNULL, X, 0, 0);
   570         -  sqliteExprSpan(A,&X->token,&E);
          568  +  sqliteExprSpan(A,&X->span,&E);
   571    569   }
   572    570   expr(A) ::= expr(X) NOTNULL(E). {
   573    571     A = sqliteExpr(TK_NOTNULL, X, 0, 0);
   574         -  sqliteExprSpan(A,&X->token,&E);
          572  +  sqliteExprSpan(A,&X->span,&E);
   575    573   }
   576    574   expr(A) ::= expr(X) NOT NULL(E). {
   577    575     A = sqliteExpr(TK_NOTNULL, X, 0, 0);
   578         -  sqliteExprSpan(A,&X->token,&E);
          576  +  sqliteExprSpan(A,&X->span,&E);
   579    577   }
   580    578   expr(A) ::= expr(X) IS NOT NULL(E). {
   581    579     A = sqliteExpr(TK_NOTNULL, X, 0, 0);
   582         -  sqliteExprSpan(A,&X->token,&E);
          580  +  sqliteExprSpan(A,&X->span,&E);
   583    581   }
   584    582   expr(A) ::= NOT(B) expr(X). {
   585    583     A = sqliteExpr(TK_NOT, X, 0, 0);
   586         -  sqliteExprSpan(A,&B,&X->token);
          584  +  sqliteExprSpan(A,&B,&X->span);
   587    585   }
   588    586   expr(A) ::= BITNOT(B) expr(X). {
   589    587     A = sqliteExpr(TK_BITNOT, X, 0, 0);
   590         -  sqliteExprSpan(A,&B,&X->token);
          588  +  sqliteExprSpan(A,&B,&X->span);
   591    589   }
   592    590   expr(A) ::= MINUS(B) expr(X). [UMINUS] {
   593    591     A = sqliteExpr(TK_UMINUS, X, 0, 0);
   594         -  sqliteExprSpan(A,&B,&X->token);
          592  +  sqliteExprSpan(A,&B,&X->span);
   595    593   }
   596    594   expr(A) ::= PLUS(B) expr(X). [UPLUS] {
   597    595     A = sqliteExpr(TK_UPLUS, X, 0, 0);
   598         -  sqliteExprSpan(A,&B,&X->token);
          596  +  sqliteExprSpan(A,&B,&X->span);
   599    597   }
   600    598   expr(A) ::= LP(B) select(X) RP(E). {
   601    599     A = sqliteExpr(TK_SELECT, 0, 0, 0);
   602    600     if( A ) A->pSelect = X;
   603    601     sqliteExprSpan(A,&B,&E);
   604    602   }
   605    603   expr(A) ::= expr(W) BETWEEN expr(X) AND expr(Y). {
   606    604     ExprList *pList = sqliteExprListAppend(0, X, 0);
   607    605     pList = sqliteExprListAppend(pList, Y, 0);
   608    606     A = sqliteExpr(TK_BETWEEN, W, 0, 0);
   609    607     if( A ) A->pList = pList;
   610         -  sqliteExprSpan(A,&W->token,&Y->token);
          608  +  sqliteExprSpan(A,&W->span,&Y->span);
   611    609   }
   612    610   expr(A) ::= expr(W) NOT BETWEEN expr(X) AND expr(Y). {
   613    611     ExprList *pList = sqliteExprListAppend(0, X, 0);
   614    612     pList = sqliteExprListAppend(pList, Y, 0);
   615    613     A = sqliteExpr(TK_BETWEEN, W, 0, 0);
   616    614     if( A ) A->pList = pList;
   617    615     A = sqliteExpr(TK_NOT, A, 0, 0);
   618         -  sqliteExprSpan(A,&W->token,&Y->token);
          616  +  sqliteExprSpan(A,&W->span,&Y->span);
   619    617   }
   620    618   expr(A) ::= expr(X) IN LP exprlist(Y) RP(E).  {
   621    619     A = sqliteExpr(TK_IN, X, 0, 0);
   622    620     if( A ) A->pList = Y;
   623         -  sqliteExprSpan(A,&X->token,&E);
          621  +  sqliteExprSpan(A,&X->span,&E);
   624    622   }
   625    623   expr(A) ::= expr(X) IN LP select(Y) RP(E).  {
   626    624     A = sqliteExpr(TK_IN, X, 0, 0);
   627    625     if( A ) A->pSelect = Y;
   628         -  sqliteExprSpan(A,&X->token,&E);
          626  +  sqliteExprSpan(A,&X->span,&E);
   629    627   }
   630    628   expr(A) ::= expr(X) NOT IN LP exprlist(Y) RP(E).  {
   631    629     A = sqliteExpr(TK_IN, X, 0, 0);
   632    630     if( A ) A->pList = Y;
   633    631     A = sqliteExpr(TK_NOT, A, 0, 0);
   634         -  sqliteExprSpan(A,&X->token,&E);
          632  +  sqliteExprSpan(A,&X->span,&E);
   635    633   }
   636    634   expr(A) ::= expr(X) NOT IN LP select(Y) RP(E).  {
   637    635     A = sqliteExpr(TK_IN, X, 0, 0);
   638    636     if( A ) A->pSelect = Y;
   639    637     A = sqliteExpr(TK_NOT, A, 0, 0);
   640         -  sqliteExprSpan(A,&X->token,&E);
          638  +  sqliteExprSpan(A,&X->span,&E);
   641    639   }
   642    640   
   643    641   /* CASE expressions */
   644    642   expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
   645    643     A = sqliteExpr(TK_CASE, X, Z, 0);
   646    644     if( A ) A->pList = Y;
   647    645     sqliteExprSpan(A, &C, &E);
................................................................................
   789    787   // SELECT
   790    788   trigger_cmd(A) ::= select(X).  {A = sqliteTriggerSelectStep(X); }
   791    789   
   792    790   // The special RAISE expression that may occur in trigger programs
   793    791   expr(A) ::= RAISE(X) LP IGNORE RP(Y).  {
   794    792     A = sqliteExpr(TK_RAISE, 0, 0, 0); 
   795    793     A->iColumn = OE_Ignore;
   796         -  /* sqliteExprSpan(A, &X, &Y); */
          794  +  sqliteExprSpan(A, &X, &Y);
   797    795   }
   798    796   expr(A) ::= RAISE(X) LP ROLLBACK COMMA nm(Z) RP(Y).  {
   799    797     A = sqliteExpr(TK_RAISE, 0, 0, &Z); 
   800    798     A->iColumn = OE_Rollback;
   801         -  /* sqliteExprSpan(A, &X, &Y); */
          799  +  sqliteExprSpan(A, &X, &Y);
   802    800   }
   803    801   expr(A) ::= RAISE(X) LP ABORT COMMA nm(Z) RP(Y).  {
   804    802     A = sqliteExpr(TK_RAISE, 0, 0, &Z); 
   805    803     A->iColumn = OE_Abort;
   806         -  /* sqliteExprSpan(A, &X, &Y); */
          804  +  sqliteExprSpan(A, &X, &Y);
   807    805   }
   808    806   expr(A) ::= RAISE(X) LP FAIL COMMA nm(Z) RP(Y).  {
   809    807     A = sqliteExpr(TK_RAISE, 0, 0, &Z); 
   810    808     A->iColumn = OE_Fail;
   811         -  /* sqliteExprSpan(A, &X, &Y); */
          809  +  sqliteExprSpan(A, &X, &Y);
   812    810   }
   813    811   
   814    812   ////////////////////////  DROP TRIGGER statement //////////////////////////////
   815    813   cmd ::= DROP TRIGGER nm(X). {
   816    814       sqliteDropTrigger(pParse,&X,0);
   817    815   }

Changes to src/select.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains C code routines that are called by the parser
    13     13   ** to handle SELECT statements in SQLite.
    14     14   **
    15         -** $Id: select.c,v 1.113 2002/10/20 15:53:04 drh Exp $
           15  +** $Id: select.c,v 1.114 2002/10/22 23:38:04 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   
    20     20   /*
    21     21   ** Allocate a new Select structure and return a pointer to that
    22     22   ** structure.
................................................................................
   153    153     Token dummy;
   154    154     Expr *pE1a, *pE1b, *pE1c;
   155    155     Expr *pE2a, *pE2b, *pE2c;
   156    156     Expr *pE;
   157    157   
   158    158     dummy.z = zCol;
   159    159     dummy.n = strlen(zCol);
   160         -  dummy.base = 1;
   161    160     dummy.dyn = 0;
   162    161     pE1a = sqliteExpr(TK_ID, 0, 0, &dummy);
   163    162     pE2a = sqliteExpr(TK_ID, 0, 0, &dummy);
   164    163     dummy.z = pTab1->zName;
   165    164     dummy.n = strlen(dummy.z);
   166    165     pE1b = sqliteExpr(TK_ID, 0, 0, &dummy);
   167    166     dummy.z = pTab2->zName;
................................................................................
   660    659         if( iCol<0 ){
   661    660           zCol = "_ROWID_";
   662    661           zType = "INTEGER";
   663    662         }else{
   664    663           zCol = pTab->aCol[iCol].zName;
   665    664           zType = pTab->aCol[iCol].zType;
   666    665         }
   667         -      if( p->token.z && p->token.z[0] && !showFullNames ){
          666  +      if( p->span.z && p->span.z[0] && !showFullNames ){
   668    667           int addr = sqliteVdbeAddOp(v,OP_ColumnName, i, 0);
   669         -        sqliteVdbeChangeP3(v, -1, p->token.z, p->token.n);
          668  +        sqliteVdbeChangeP3(v, -1, p->span.z, p->span.n);
   670    669           sqliteVdbeCompressSpace(v, addr);
   671    670         }else if( pTabList->nSrc>1 || showFullNames ){
   672    671           char *zName = 0;
   673    672           char *zTab;
   674    673    
   675    674           zTab = pTabList->a[p->iTable - base].zAlias;
   676    675           if( showFullNames || zTab==0 ) zTab = pTab->zName;
................................................................................
   678    677           sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
   679    678           sqliteVdbeChangeP3(v, -1, zName, strlen(zName));
   680    679           sqliteFree(zName);
   681    680         }else{
   682    681           sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
   683    682           sqliteVdbeChangeP3(v, -1, zCol, 0);
   684    683         }
   685         -    }else if( p->token.z && p->token.z[0] && !showFullNames ){
          684  +    }else if( p->span.z && p->span.z[0] ){
   686    685         int addr = sqliteVdbeAddOp(v,OP_ColumnName, i, 0);
   687         -      sqliteVdbeChangeP3(v, -1, p->token.z, p->token.n);
   688         -      sqliteVdbeCompressSpace(v, addr);
   689         -    }else if( p->token.z && p->token.z[0] ){
   690         -      int addr = sqliteVdbeAddOp(v,OP_ColumnName, i, 0);
   691         -      sqliteVdbeChangeP3(v, -1, p->token.z, p->token.n);
          686  +      sqliteVdbeChangeP3(v, -1, p->span.z, p->span.n);
   692    687         sqliteVdbeCompressSpace(v, addr);
   693    688       }else{
   694    689         char zName[30];
   695    690         assert( p->op!=TK_COLUMN || pTabList==0 );
   696    691         sprintf(zName, "column%d", i+1);
   697    692         sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
   698    693         sqliteVdbeChangeP3(v, -1, zName, strlen(zName));
................................................................................
   751    746     pTab->nCol = pEList->nExpr;
   752    747     assert( pTab->nCol>0 );
   753    748     pTab->aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol );
   754    749     for(i=0; i<pTab->nCol; i++){
   755    750       Expr *p;
   756    751       if( pEList->a[i].zName ){
   757    752         pTab->aCol[i].zName = sqliteStrDup(pEList->a[i].zName);
   758         -    }else if( (p=pEList->a[i].pExpr)->token.z && p->token.z[0] ){
   759         -      sqliteSetNString(&pTab->aCol[i].zName, p->token.z, p->token.n, 0);
          753  +    }else if( (p=pEList->a[i].pExpr)->span.z && p->span.z[0] ){
          754  +      sqliteSetNString(&pTab->aCol[i].zName, p->span.z, p->span.n, 0);
   760    755       }else if( p->op==TK_DOT && p->pRight && p->pRight->token.z &&
   761    756              p->pRight->token.z[0] ){
   762    757         sqliteSetNString(&pTab->aCol[i].zName, 
   763    758              p->pRight->token.z, p->pRight->token.n, 0);
   764    759       }else{
   765    760         char zBuf[30];
   766    761         sprintf(zBuf, "column%d", i+1);
................................................................................
   918    913                 continue;
   919    914               }
   920    915               pRight = sqliteExpr(TK_ID, 0, 0, 0);
   921    916               if( pRight==0 ) break;
   922    917               pRight->token.z = zName;
   923    918               pRight->token.n = strlen(zName);
   924    919               pRight->token.dyn = 0;
   925         -            pRight->token.base = 1;
   926    920               if( zTabName && pTabList->nSrc>1 ){
   927    921                 pLeft = sqliteExpr(TK_ID, 0, 0, 0);
   928    922                 pExpr = sqliteExpr(TK_DOT, pLeft, pRight, 0);
   929    923                 if( pExpr==0 ) break;
   930    924                 pLeft->token.z = zTabName;
   931    925                 pLeft->token.n = strlen(zTabName);
   932    926                 pLeft->token.dyn = 0;
   933         -              pLeft->token.base = 1;
   934         -              sqliteSetString((char**)&pExpr->token.z, zTabName, ".", zName, 0);
   935         -              pExpr->token.n = strlen(pExpr->token.z);
   936         -              pExpr->token.base = 0;
   937         -              pExpr->token.dyn = 1;
          927  +              sqliteSetString((char**)&pExpr->span.z, zTabName, ".", zName, 0);
          928  +              pExpr->span.n = strlen(pExpr->span.z);
          929  +              pExpr->span.dyn = 1;
          930  +              pExpr->token.z = 0;
          931  +              pExpr->token.n = 0;
          932  +              pExpr->token.dyn = 0;
   938    933               }else{
   939    934                 pExpr = pRight;
          935  +              pExpr->span = pExpr->token;
   940    936               }
   941    937               pNew = sqliteExprListAppend(pNew, pExpr, 0);
   942    938             }
   943    939           }
   944    940           if( !tableSeen ){
   945    941             if( pName ){
   946    942               sqliteSetNString(&pParse->zErrMsg, "no such table: ", -1, 
................................................................................
  1340   1336       assert( pExpr->pRight==0 );
  1341   1337       pExpr->pRight = sqliteExprDup(pNew->pRight);
  1342   1338       assert( pExpr->pList==0 );
  1343   1339       pExpr->pList = sqliteExprListDup(pNew->pList);
  1344   1340       pExpr->iTable = pNew->iTable;
  1345   1341       pExpr->iColumn = pNew->iColumn;
  1346   1342       pExpr->iAgg = pNew->iAgg;
  1347         -    pExpr->nFuncName = pNew->nFuncName;
  1348   1343       sqliteTokenCopy(&pExpr->token, &pNew->token);
         1344  +    sqliteTokenCopy(&pExpr->span, &pNew->span);
  1349   1345       if( iSub!=iTable ){
  1350   1346         changeTables(pExpr, iSub, iTable);
  1351   1347       }
  1352   1348     }else{
  1353   1349       substExpr(pExpr->pLeft, iTable, pEList, iSub);
  1354   1350       substExpr(pExpr->pRight, iTable, pEList, iSub);
  1355   1351       substExprList(pExpr->pList, iTable, pEList, iSub);
................................................................................
  1463   1459     ** i-th entry of the FROM clause in the outer query.
  1464   1460     */
  1465   1461     iParent = p->base + iFrom;
  1466   1462     iSub = pSub->base;
  1467   1463     substExprList(p->pEList, iParent, pSub->pEList, iSub);
  1468   1464     pList = p->pEList;
  1469   1465     for(i=0; i<pList->nExpr; i++){
  1470         -    if( pList->a[i].zName==0 ){
  1471         -      Expr *pExpr = pList->a[i].pExpr;
  1472         -      assert( pExpr->token.z!=0 );
  1473         -      pList->a[i].zName = sqliteStrNDup(pExpr->token.z, pExpr->token.n);
         1466  +    Expr *pExpr;
         1467  +    if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){
         1468  +      pList->a[i].zName = sqliteStrNDup(pExpr->span.z, pExpr->span.n);
  1474   1469       }
  1475   1470     }
  1476   1471     if( isAgg ){
  1477   1472       substExprList(p->pGroupBy, iParent, pSub->pEList, iSub);
  1478   1473       substExpr(p->pHaving, iParent, pSub->pEList, iSub);
  1479   1474     }
  1480   1475     substExprList(p->pOrderBy, iParent, pSub->pEList, iSub);
................................................................................
  1589   1584     */
  1590   1585     if( p->pGroupBy || p->pHaving || p->pWhere ) return 0;
  1591   1586     if( p->pSrc->nSrc!=1 ) return 0;
  1592   1587     if( p->pEList->nExpr!=1 ) return 0;
  1593   1588     pExpr = p->pEList->a[0].pExpr;
  1594   1589     if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
  1595   1590     if( pExpr->pList==0 || pExpr->pList->nExpr!=1 ) return 0;
  1596         -  if( pExpr->nFuncName!=3 ) return 0;
         1591  +  if( pExpr->token.n!=3 ) return 0;
  1597   1592     if( sqliteStrNICmp(pExpr->token.z,"min",3)==0 ){
  1598   1593       seekOp = OP_Rewind;
  1599   1594     }else if( sqliteStrNICmp(pExpr->token.z,"max",3)==0 ){
  1600   1595       seekOp = OP_Last;
  1601   1596     }else{
  1602   1597       return 0;
  1603   1598     }

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.146 2002/09/14 13:47:32 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.147 2002/10/22 23:38:04 drh Exp $
    15     15   */
    16     16   #include "sqlite.h"
    17     17   #include "hash.h"
    18     18   #include "vdbe.h"
    19     19   #include "parse.h"
    20     20   #include "btree.h"
    21     21   #include <stdio.h>
................................................................................
   445    445     u8 autoIndex;    /* True if is automatically created (ex: by UNIQUE) */
   446    446     Index *pNext;    /* The next index associated with the same table */
   447    447   };
   448    448   
   449    449   /*
   450    450   ** Each token coming out of the lexer is an instance of
   451    451   ** this structure.  Tokens are also used as part of an expression.
   452         -**
   453         -** A "base" token is a real single token such as would come out of the
   454         -** lexer.  There are also compound tokens which are aggregates of one
   455         -** or more base tokens.  Compound tokens are used to name columns in the
   456         -** result set of a SELECT statement.  In the expression "a+b+c", "b"
   457         -** is a base token but "a+b" is a compound token.
   458    452   */
   459    453   struct Token {
   460    454     const char *z;      /* Text of the token.  Not NULL-terminated! */
   461    455     unsigned dyn  : 1;  /* True for malloced memory, false for static */
   462         -  unsigned base : 1;  /* True for a base token, false for compounds */
   463         -  unsigned n    : 30; /* Number of characters in this token */
          456  +  unsigned n    : 31; /* Number of characters in this token */
   464    457   };
   465    458   
   466    459   /*
   467    460   ** Each node of an expression in the parse tree is an instance
   468    461   ** of this structure.
   469    462   **
   470    463   ** Expr.op is the opcode.  The integer parser token codes are reused
................................................................................
   497    490   ** in an expression the opcode is TK_SELECT and Expr.pSelect is the only
   498    491   ** operand.
   499    492   */
   500    493   struct Expr {
   501    494     u8 op;                 /* Operation performed by this node */
   502    495     u8 dataType;           /* Either SQLITE_SO_TEXT or SQLITE_SO_NUM */
   503    496     u8 isJoinExpr;         /* Origin is the ON or USING phrase of a join */
   504         -  u8 nFuncName;          /* Number of characters in a function name */
   505    497     Expr *pLeft, *pRight;  /* Left and right subnodes */
   506    498     ExprList *pList;       /* A list of expressions used as function arguments
   507    499                            ** or in "<expr> IN (<expr-list)" */
   508    500     Token token;           /* An operand token */
          501  +  Token span;            /* Complete text of the expression */
   509    502     int iTable, iColumn;   /* When op==TK_COLUMN, then this expr node means the
   510    503                            ** iColumn-th field of the iTable-th table. */
   511    504     int iAgg;              /* When op==TK_COLUMN and pParse->useAgg==TRUE, pull
   512    505                            ** result from the iAgg-th element of the aggregator */
   513    506     Select *pSelect;       /* When the expression is a sub-select.  Also the
   514    507                            ** right side of "<expr> IN (<select>)" */
   515    508   };

Changes to src/tokenize.c.

    11     11   *************************************************************************
    12     12   ** An tokenizer for SQL
    13     13   **
    14     14   ** This file contains C code that splits an SQL input string up into
    15     15   ** individual tokens and sends those tokens one-by-one over to the
    16     16   ** parser for analysis.
    17     17   **
    18         -** $Id: tokenize.c,v 1.49 2002/08/27 14:28:30 drh Exp $
           18  +** $Id: tokenize.c,v 1.50 2002/10/22 23:38:04 drh Exp $
    19     19   */
    20     20   #include "sqliteInt.h"
    21     21   #include "os.h"
    22     22   #include <ctype.h>
    23     23   #include <stdlib.h>
    24     24   
    25     25   /*
................................................................................
   420    420       
   421    421       if( (db->flags & SQLITE_Interrupt)!=0 ){
   422    422         pParse->rc = SQLITE_INTERRUPT;
   423    423         sqliteSetString(pzErrMsg, "interrupt", 0);
   424    424         break;
   425    425       }
   426    426       pParse->sLastToken.z = &zSql[i];
   427         -    pParse->sLastToken.base = 1;
   428    427       pParse->sLastToken.dyn = 0;
   429    428       pParse->sLastToken.n = sqliteGetToken((unsigned char*)&zSql[i], &tokenType);
   430    429       i += pParse->sLastToken.n;
   431    430       if( once ){
   432    431         pParse->sFirstToken = pParse->sLastToken;
   433    432         once = 0;
   434    433       }

Changes to test/misc1.test.

     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.
    12     12   #
    13     13   # This file implements tests for miscellanous features that were
    14     14   # left out of other test files.
    15     15   #
    16         -# $Id: misc1.test,v 1.15 2002/09/17 03:20:46 drh Exp $
           16  +# $Id: misc1.test,v 1.16 2002/10/22 23:38:04 drh Exp $
    17     17   
    18     18   set testdir [file dirname $argv0]
    19     19   source $testdir/tester.tcl
    20     20   
    21     21   # Test the creation and use of tables that have a large number
    22     22   # of columns.
    23     23   #
................................................................................
    99     99     }
   100    100     execsql {SELECT count(*) FROM agger}
   101    101   } 6
   102    102   do_test misc1-2.2 {
   103    103     execsql {SELECT sum(one), two, four FROM agger
   104    104              GROUP BY two, four ORDER BY sum(one) desc}
   105    105   } {8 two no 6 one yes 4 two yes 3 thr yes}
          106  +do_test misc1-2.3 {
          107  +  execsql {SELECT sum((one)), (two), (four) FROM agger
          108  +           GROUP BY (two), (four) ORDER BY sum(one) desc}
          109  +} {8 two no 6 one yes 4 two yes 3 thr yes}
   106    110   
   107    111   # Here's a test for a bug found by Joel Lucsy.  The code below
   108    112   # was causing an assertion failure.
   109    113   #
   110    114   do_test misc1-3.1 {
   111    115     set r [execsql {
   112    116       CREATE TABLE t1(a);

Changes to test/where.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is testing the use of indices in WHERE clases.
    13     13   #
    14         -# $Id: where.test,v 1.10 2002/08/14 03:03:58 drh Exp $
           14  +# $Id: where.test,v 1.11 2002/10/22 23:38:04 drh Exp $
    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
    18     18   
    19     19   # Build some test data
    20     20   #
    21     21   do_test where-1.0 {
................................................................................
   165    165   } {1 2 4}
   166    166   do_test where-1.36 {
   167    167     count {SELECT w FROM t1 WHERE w<=3}
   168    168   } {1 2 3 6}
   169    169   do_test where-1.37 {
   170    170     count {SELECT w FROM t1 WHERE w+1<=4 ORDER BY w}
   171    171   } {1 2 3 199}
          172  +
          173  +do_test where-1.38 {
          174  +  count {SELECT (w) FROM t1 WHERE (w)>(97)}
          175  +} {98 99 100 6}
          176  +do_test where-1.39 {
          177  +  count {SELECT (w) FROM t1 WHERE (w)>=(97)}
          178  +} {97 98 99 100 8}
          179  +do_test where-1.40 {
          180  +  count {SELECT (w) FROM t1 WHERE (w)==(97)}
          181  +} {97 3}
          182  +do_test where-1.41 {
          183  +  count {SELECT (w) FROM t1 WHERE ((w)+(1))==(98)}
          184  +} {97 99}
   172    185   
   173    186   
   174    187   # Do the same kind of thing except use a join as the data source.
   175    188   #
   176    189   do_test where-2.1 {
   177    190     count {
   178    191       SELECT w, p FROM t2, t1