/ Check-in [9c411c3c]
Login

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

Overview
Comment:Optimizations on the SELECT code generator. (CVS 1926)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 9c411c3c8dde2061c98513a413ef58c5c2de45af
User & Date: drh 2004-09-01 03:06:35
Context
2004-09-01
16:12
Work around a bug in the Borland C++ compiler. Ticket #881. (CVS 1927) check-in: 18af6ba5 user: drh tags: trunk
03:06
Optimizations on the SELECT code generator. (CVS 1926) check-in: 9c411c3c user: drh tags: trunk
2004-08-31
23:41
Changes to support compiling under windows. (CVS 1925) check-in: 68a712f3 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.158 2004/08/31 13:45:12 drh Exp $
           15  +** $Id: expr.c,v 1.159 2004/09/01 03:06:35 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   #include <ctype.h>
    19     19   
    20     20   char const *sqlite3AffinityString(char affinity){
    21     21     switch( affinity ){
    22     22       case SQLITE_AFF_INTEGER: return "i";
................................................................................
   214    214         sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span);
   215    215       }else{
   216    216         pNew->span = pNew->token;
   217    217       }
   218    218     }
   219    219     return pNew;
   220    220   }
          221  +
          222  +/*
          223  +** Join two expressions using an AND operator.  If either expression is
          224  +** NULL, then just return the other expression.
          225  +*/
          226  +Expr *sqlite3ExprAnd(Expr *pLeft, Expr *pRight){
          227  +  if( pLeft==0 ){
          228  +    return pRight;
          229  +  }else if( pRight==0 ){
          230  +    return pLeft;
          231  +  }else{
          232  +    return sqlite3Expr(TK_AND, pLeft, pRight, 0);
          233  +  }
          234  +}
   221    235   
   222    236   /*
   223    237   ** Set the Expr.span field of the given expression to span all
   224    238   ** text between the two given tokens.
   225    239   */
   226    240   void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
   227    241     assert( pRight!=0 );

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.205 2004/08/29 16:25:04 drh Exp $
           15  +** $Id: select.c,v 1.206 2004/09/01 03:06:35 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.
................................................................................
   139    139   static int columnIndex(Table *pTab, const char *zCol){
   140    140     int i;
   141    141     for(i=0; i<pTab->nCol; i++){
   142    142       if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i;
   143    143     }
   144    144     return -1;
   145    145   }
          146  +
          147  +/*
          148  +** Set the value of a token to a '\000'-terminated string.
          149  +*/
          150  +static void setToken(Token *p, const char *z){
          151  +  p->z = z;
          152  +  p->n = strlen(z);
          153  +  p->dyn = 0;
          154  +}
          155  +
   146    156   
   147    157   /*
   148    158   ** Add a term to the WHERE expression in *ppExpr that requires the
   149    159   ** zCol column to be equal in the two tables pTab1 and pTab2.
   150    160   */
   151    161   static void addWhereTerm(
   152    162     const char *zCol,        /* Name of the column */
................................................................................
   155    165     Expr **ppExpr            /* Add the equality term to this expression */
   156    166   ){
   157    167     Token dummy;
   158    168     Expr *pE1a, *pE1b, *pE1c;
   159    169     Expr *pE2a, *pE2b, *pE2c;
   160    170     Expr *pE;
   161    171   
   162         -  dummy.z = zCol;
   163         -  dummy.n = strlen(zCol);
   164         -  dummy.dyn = 0;
          172  +  setToken(&dummy, zCol);
   165    173     pE1a = sqlite3Expr(TK_ID, 0, 0, &dummy);
   166    174     pE2a = sqlite3Expr(TK_ID, 0, 0, &dummy);
   167         -  dummy.z = pTab1->zName;
   168         -  dummy.n = strlen(dummy.z);
          175  +  setToken(&dummy, pTab1->zName);
   169    176     pE1b = sqlite3Expr(TK_ID, 0, 0, &dummy);
   170         -  dummy.z = pTab2->zName;
   171         -  dummy.n = strlen(dummy.z);
          177  +  setToken(&dummy, pTab2->zName);
   172    178     pE2b = sqlite3Expr(TK_ID, 0, 0, &dummy);
   173    179     pE1c = sqlite3Expr(TK_DOT, pE1b, pE1a, 0);
   174    180     pE2c = sqlite3Expr(TK_DOT, pE2b, pE2a, 0);
   175    181     pE = sqlite3Expr(TK_EQ, pE1c, pE2c, 0);
   176    182     ExprSetProperty(pE, EP_FromJoin);
   177         -  if( *ppExpr ){
   178         -    *ppExpr = sqlite3Expr(TK_AND, *ppExpr, pE, 0);
   179         -  }else{
   180         -    *ppExpr = pE;
   181         -  }
          183  +  *ppExpr = sqlite3ExprAnd(*ppExpr, pE);
   182    184   }
   183    185   
   184    186   /*
   185    187   ** Set the EP_FromJoin property on all terms of the given expression.
   186    188   **
   187    189   ** The EP_FromJoin property is used on terms of an expression to tell
   188    190   ** the LEFT OUTER JOIN processing logic that this term is part of the
................................................................................
   199    201     } 
   200    202   }
   201    203   
   202    204   /*
   203    205   ** This routine processes the join information for a SELECT statement.
   204    206   ** ON and USING clauses are converted into extra terms of the WHERE clause.
   205    207   ** NATURAL joins also create extra WHERE clause terms.
          208  +**
          209  +** The terms of a FROM clause are contained in the Select.pSrc structure.
          210  +** The left most table is the first entry in Select.pSrc.  The right-most
          211  +** table is the last entry.  The join operator is held in the entry to
          212  +** the left.  Thus entry 0 contains the join operator for the join between
          213  +** entries 0 and 1.  Any ON or USING clauses associated with the join are
          214  +** also attached to the left entry.
   206    215   **
   207    216   ** This routine returns the number of errors encountered.
   208    217   */
   209    218   static int sqliteProcessJoin(Parse *pParse, Select *p){
   210         -  SrcList *pSrc;
   211         -  int i, j;
          219  +  SrcList *pSrc;                  /* All tables in the FROM clause */
          220  +  int i, j;                       /* Loop counters */
          221  +  struct SrcList_item *pLeft;     /* Left table being joined */
          222  +  struct SrcList_item *pRight;    /* Right table being joined */
          223  +
   212    224     pSrc = p->pSrc;
   213         -  for(i=0; i<pSrc->nSrc-1; i++){
   214         -    struct SrcList_item *pTerm = &pSrc->a[i];
   215         -    struct SrcList_item *pOther = &pSrc->a[i+1];
          225  +  pLeft = &pSrc->a[0];
          226  +  pRight = &pLeft[1];
          227  +  for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
          228  +    Table *pLeftTab = pLeft->pTab;
          229  +    Table *pRightTab = pRight->pTab;
   216    230   
   217         -    if( pTerm->pTab==0 || pOther->pTab==0 ) continue;
          231  +    if( pLeftTab==0 || pRightTab==0 ) continue;
   218    232   
   219    233       /* When the NATURAL keyword is present, add WHERE clause terms for
   220    234       ** every column that the two tables have in common.
   221    235       */
   222         -    if( pTerm->jointype & JT_NATURAL ){
   223         -      Table *pTab;
   224         -      if( pTerm->pOn || pTerm->pUsing ){
          236  +    if( pLeft->jointype & JT_NATURAL ){
          237  +      if( pLeft->pOn || pLeft->pUsing ){
   225    238           sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
   226    239              "an ON or USING clause", 0);
   227    240           return 1;
   228    241         }
   229         -      pTab = pTerm->pTab;
   230         -      for(j=0; j<pTab->nCol; j++){
   231         -        if( columnIndex(pOther->pTab, pTab->aCol[j].zName)>=0 ){
   232         -          addWhereTerm(pTab->aCol[j].zName, pTab, pOther->pTab, &p->pWhere);
          242  +      for(j=0; j<pLeftTab->nCol; j++){
          243  +        char *zName = pLeftTab->aCol[j].zName;
          244  +        if( columnIndex(pRightTab, zName)>=0 ){
          245  +          addWhereTerm(zName, pLeftTab, pRightTab, &p->pWhere);
   233    246           }
   234    247         }
   235    248       }
   236    249   
   237    250       /* Disallow both ON and USING clauses in the same join
   238    251       */
   239         -    if( pTerm->pOn && pTerm->pUsing ){
          252  +    if( pLeft->pOn && pLeft->pUsing ){
   240    253         sqlite3ErrorMsg(pParse, "cannot have both ON and USING "
   241    254           "clauses in the same join");
   242    255         return 1;
   243    256       }
   244    257   
   245    258       /* Add the ON clause to the end of the WHERE clause, connected by
   246         -    ** and AND operator.
          259  +    ** an AND operator.
   247    260       */
   248         -    if( pTerm->pOn ){
   249         -      setJoinExpr(pTerm->pOn);
   250         -      if( p->pWhere==0 ){
   251         -        p->pWhere = pTerm->pOn;
   252         -      }else{
   253         -        p->pWhere = sqlite3Expr(TK_AND, p->pWhere, pTerm->pOn, 0);
   254         -      }
   255         -      pTerm->pOn = 0;
          261  +    if( pLeft->pOn ){
          262  +      setJoinExpr(pLeft->pOn);
          263  +      p->pWhere = sqlite3ExprAnd(p->pWhere, pLeft->pOn);
          264  +      pLeft->pOn = 0;
   256    265       }
   257    266   
   258    267       /* Create extra terms on the WHERE clause for each column named
   259    268       ** in the USING clause.  Example: If the two tables to be joined are 
   260    269       ** A and B and the USING clause names X, Y, and Z, then add this
   261    270       ** to the WHERE clause:    A.X=B.X AND A.Y=B.Y AND A.Z=B.Z
   262    271       ** Report an error if any column mentioned in the USING clause is
   263    272       ** not contained in both tables to be joined.
   264    273       */
   265         -    if( pTerm->pUsing ){
   266         -      IdList *pList;
   267         -      int j;
   268         -      assert( i<pSrc->nSrc-1 );
   269         -      pList = pTerm->pUsing;
          274  +    if( pLeft->pUsing ){
          275  +      IdList *pList = pLeft->pUsing;
   270    276         for(j=0; j<pList->nId; j++){
   271         -        if( columnIndex(pTerm->pTab, pList->a[j].zName)<0 ||
   272         -            columnIndex(pOther->pTab, pList->a[j].zName)<0 ){
          277  +        char *zName = pList->a[j].zName;
          278  +        if( columnIndex(pLeftTab, zName)<0 || columnIndex(pRightTab, zName)<0 ){
   273    279             sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
   274         -            "not present in both tables", pList->a[j].zName);
          280  +            "not present in both tables", zName);
   275    281             return 1;
   276    282           }
   277         -        addWhereTerm(pList->a[j].zName, pTerm->pTab, pOther->pTab, &p->pWhere);
          283  +        addWhereTerm(zName, pLeftTab, pRightTab, &p->pWhere);
   278    284         }
   279    285       }
   280    286     }
   281    287     return 0;
   282    288   }
   283    289   
   284    290   /*
................................................................................
   817    823     pEList = pSelect->pEList;
   818    824     pTab->nCol = pEList->nExpr;
   819    825     assert( pTab->nCol>0 );
   820    826     pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol );
   821    827     for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){
   822    828       Expr *pR;
   823    829       char *zType;
          830  +    char *zName;
   824    831       Expr *p = pEList->a[i].pExpr;
   825    832       assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 );
   826         -    if( pEList->a[i].zName ){
   827         -      pCol->zName = sqliteStrDup(pEList->a[i].zName);
          833  +    if( (zName = pEList->a[i].zName)!=0 ){
          834  +      zName = sqliteStrDup(zName);
   828    835       }else if( p->op==TK_DOT 
   829    836                  && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){
   830    837         int cnt;
   831         -      sqlite3SetNString(&pCol->zName, pR->token.z, pR->token.n, 0);
          838  +      zName = sqlite3MPrintf("%T", &pR->token);
   832    839         for(j=cnt=0; j<i; j++){
   833         -        if( sqlite3StrICmp(aCol[j].zName, pCol->zName)==0 ){
   834         -          int n;
   835         -          char zBuf[30];
   836         -          sprintf(zBuf,"_%d",++cnt);
   837         -          n = strlen(zBuf);
   838         -          sqlite3SetNString(&pCol->zName, pR->token.z, pR->token.n, zBuf,n,0);
          840  +        if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
          841  +          sqliteFree(zName);
          842  +          zName = sqlite3MPrintf("%T_%d", &pR->token, ++cnt);
   839    843             j = -1;
   840    844           }
   841    845         }
   842    846       }else if( p->span.z && p->span.z[0] ){
   843         -      sqlite3SetNString(&pCol->zName, p->span.z, p->span.n, 0);
          847  +      zName = sqlite3MPrintf("%T", &p->span);
   844    848       }else{
   845         -      char zBuf[30];
   846         -      sprintf(zBuf, "column%d", i+1);
   847         -      pCol->zName = sqliteStrDup(zBuf);
          849  +      zName = sqlite3MPrintf("column%d", i+1);
   848    850       }
   849         -    sqlite3Dequote(pCol->zName);
          851  +    sqlite3Dequote(zName);
          852  +    pCol->zName = zName;
   850    853   
   851    854       zType = sqliteStrDup(columnType(pParse, pSelect->pSrc ,p));
   852    855       pCol->zType = zType;
   853    856       pCol->affinity = SQLITE_AFF_NUMERIC;
   854    857       if( zType ){
   855    858         pCol->affinity = sqlite3AffinityType(zType, strlen(zType));
   856    859       }
................................................................................
   903    906         /* This routine has run before!  No need to continue */
   904    907         return 0;
   905    908       }
   906    909       if( pFrom->zName==0 ){
   907    910         /* A sub-query in the FROM clause of a SELECT */
   908    911         assert( pFrom->pSelect!=0 );
   909    912         if( pFrom->zAlias==0 ){
   910         -        char zFakeName[60];
   911         -        sprintf(zFakeName, "sqlite_subquery_%p_", (void*)pFrom->pSelect);
   912         -        sqlite3SetString(&pFrom->zAlias, zFakeName, 0);
          913  +        pFrom->zAlias =
          914  +          sqlite3MPrintf("sqlite_subquery_%p_", (void*)pFrom->pSelect);
   913    915         }
   914    916         pFrom->pTab = pTab = 
   915    917           sqlite3ResultSetOfSelect(pParse, pFrom->zAlias, pFrom->pSelect);
   916    918         if( pTab==0 ){
   917    919           return 1;
   918    920         }
   919    921         /* The isTransient flag indicates that the Table structure has been
................................................................................
  1005   1007               continue;
  1006   1008             }
  1007   1009             tableSeen = 1;
  1008   1010             for(j=0; j<pTab->nCol; j++){
  1009   1011               Expr *pExpr, *pLeft, *pRight;
  1010   1012               char *zName = pTab->aCol[j].zName;
  1011   1013   
  1012         -            if( i>0 && (pTabList->a[i-1].jointype & JT_NATURAL)!=0 &&
  1013         -                columnIndex(pTabList->a[i-1].pTab, zName)>=0 ){
  1014         -              /* In a NATURAL join, omit the join columns from the 
  1015         -              ** table on the right */
  1016         -              continue;
  1017         -            }
  1018         -            if( i>0 && sqlite3IdListIndex(pTabList->a[i-1].pUsing, zName)>=0 ){
  1019         -              /* In a join with a USING clause, omit columns in the
  1020         -              ** using clause from the table on the right. */
  1021         -              continue;
         1014  +            if( i>0 ){
         1015  +              struct SrcList_item *pLeft = &pTabList->a[i-1];
         1016  +              if( (pLeft->jointype & JT_NATURAL)!=0 &&
         1017  +                        columnIndex(pLeft->pTab, zName)>=0 ){
         1018  +                /* In a NATURAL join, omit the join columns from the 
         1019  +                ** table on the right */
         1020  +                continue;
         1021  +              }
         1022  +              if( sqlite3IdListIndex(pLeft->pUsing, zName)>=0 ){
         1023  +                /* In a join with a USING clause, omit columns in the
         1024  +                ** using clause from the table on the right. */
         1025  +                continue;
         1026  +              }
  1022   1027               }
  1023   1028               pRight = sqlite3Expr(TK_ID, 0, 0, 0);
  1024   1029               if( pRight==0 ) break;
  1025         -            pRight->token.z = zName;
  1026         -            pRight->token.n = strlen(zName);
  1027         -            pRight->token.dyn = 0;
         1030  +            setToken(&pRight->token, zName);
  1028   1031               if( zTabName && pTabList->nSrc>1 ){
  1029   1032                 pLeft = sqlite3Expr(TK_ID, 0, 0, 0);
  1030   1033                 pExpr = sqlite3Expr(TK_DOT, pLeft, pRight, 0);
  1031   1034                 if( pExpr==0 ) break;
  1032         -              pLeft->token.z = zTabName;
  1033         -              pLeft->token.n = strlen(zTabName);
  1034         -              pLeft->token.dyn = 0;
  1035         -              sqlite3SetString((char**)&pExpr->span.z, zTabName, ".", zName, 0);
  1036         -              pExpr->span.n = strlen(pExpr->span.z);
         1035  +              setToken(&pLeft->token, zTabName);
         1036  +              setToken(&pExpr->span, sqlite3MPrintf("%s.%s", zTabName, zName));
  1037   1037                 pExpr->span.dyn = 1;
  1038   1038                 pExpr->token.z = 0;
  1039   1039                 pExpr->token.n = 0;
  1040   1040                 pExpr->token.dyn = 0;
  1041   1041               }else{
  1042   1042                 pExpr = pRight;
  1043   1043                 pExpr->span = pExpr->token;
................................................................................
  1074   1074   ** If the bindings are not removed, then the Select.pSrc->a[].pTab field
  1075   1075   ** will be left pointing to a deallocated Table structure after the
  1076   1076   ** DROP and a coredump will occur the next time the VIEW is used.
  1077   1077   */
  1078   1078   void sqlite3SelectUnbind(Select *p){
  1079   1079     int i;
  1080   1080     SrcList *pSrc = p->pSrc;
         1081  +  struct SrcList_item *pItem;
  1081   1082     Table *pTab;
  1082   1083     if( p==0 ) return;
  1083         -  for(i=0; i<pSrc->nSrc; i++){
  1084         -    if( (pTab = pSrc->a[i].pTab)!=0 ){
         1084  +  for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){
         1085  +    if( (pTab = pItem->pTab)!=0 ){
  1085   1086         if( pTab->isTransient ){
  1086   1087           sqlite3DeleteTable(0, pTab);
  1087   1088         }
  1088         -      pSrc->a[i].pTab = 0;
  1089         -      if( pSrc->a[i].pSelect ){
  1090         -        sqlite3SelectUnbind(pSrc->a[i].pSelect);
         1089  +      pItem->pTab = 0;
         1090  +      if( pItem->pSelect ){
         1091  +        sqlite3SelectUnbind(pItem->pSelect);
  1091   1092         }
  1092   1093       }
  1093   1094     }
  1094   1095   }
  1095   1096   
  1096   1097   /*
  1097   1098   ** This routine associates entries in an ORDER BY expression list with
................................................................................
  1259   1260   
  1260   1261     if( fillInColumnList(pParse, p) ){
  1261   1262       return 0;
  1262   1263     }
  1263   1264     nColumn = p->pEList->nExpr;
  1264   1265     pKeyInfo = sqliteMalloc( sizeof(*pKeyInfo)+nColumn*sizeof(CollSeq*) );
  1265   1266     if( pKeyInfo==0 ) return 0;
  1266         -  pKeyInfo->enc = pParse->db->enc;
         1267  +  pKeyInfo->enc = db->enc;
  1267   1268     pKeyInfo->nField = nColumn;
  1268   1269     for(i=0; i<nColumn; i++){
  1269   1270       pKeyInfo->aColl[i] = sqlite3ExprCollSeq(pParse, p->pEList->a[i].pExpr);
  1270   1271       if( !pKeyInfo->aColl[i] ){
  1271   1272         pKeyInfo->aColl[i] = db->pDfltColl;
  1272   1273       }
  1273   1274     }
................................................................................
  1832   1833     int subqueryIsAgg    /* True if the subquery uses aggregate functions */
  1833   1834   ){
  1834   1835     Select *pSub;       /* The inner query or "subquery" */
  1835   1836     SrcList *pSrc;      /* The FROM clause of the outer query */
  1836   1837     SrcList *pSubSrc;   /* The FROM clause of the subquery */
  1837   1838     ExprList *pList;    /* The result set of the outer query */
  1838   1839     int iParent;        /* VDBE cursor number of the pSub result set temp table */
  1839         -  int i;
  1840         -  Expr *pWhere;
         1840  +  int i;              /* Loop counter */
         1841  +  Expr *pWhere;                    /* The WHERE clause */
         1842  +  struct SrcList_item *pSubitem;   /* The subquery */
  1841   1843   
  1842   1844     /* Check to see if flattening is permitted.  Return 0 if not.
  1843   1845     */
  1844   1846     if( p==0 ) return 0;
  1845   1847     pSrc = p->pSrc;
  1846   1848     assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
  1847         -  pSub = pSrc->a[iFrom].pSelect;
         1849  +  pSubitem = &pSrc->a[iFrom];
         1850  +  pSub = pSubitem->pSelect;
  1848   1851     assert( pSub!=0 );
  1849   1852     if( isAgg && subqueryIsAgg ) return 0;
  1850   1853     if( subqueryIsAgg && pSrc->nSrc>1 ) return 0;
  1851   1854     pSubSrc = pSub->pSrc;
  1852   1855     assert( pSubSrc );
  1853   1856     if( pSubSrc->nSrc==0 ) return 0;
  1854   1857     if( (pSub->isDistinct || pSub->nLimit>=0) &&  (pSrc->nSrc>1 || isAgg) ){
................................................................................
  1899   1902     ** the FROM clause of the outer query.  Before doing this, remember
  1900   1903     ** the cursor number for the original outer query FROM element in
  1901   1904     ** iParent.  The iParent cursor will never be used.  Subsequent code
  1902   1905     ** will scan expressions looking for iParent references and replace
  1903   1906     ** those references with expressions that resolve to the subquery FROM
  1904   1907     ** elements we are now copying in.
  1905   1908     */
  1906         -  iParent = pSrc->a[iFrom].iCursor;
         1909  +  iParent = pSubitem->iCursor;
  1907   1910     {
  1908   1911       int nSubSrc = pSubSrc->nSrc;
  1909         -    int jointype = pSrc->a[iFrom].jointype;
         1912  +    int jointype = pSubitem->jointype;
         1913  +    Table *pTab = pSubitem->pTab;
  1910   1914   
  1911         -    if( pSrc->a[iFrom].pTab && pSrc->a[iFrom].pTab->isTransient ){
  1912         -      sqlite3DeleteTable(0, pSrc->a[iFrom].pTab);
         1915  +    if( pTab && pTab->isTransient ){
         1916  +      sqlite3DeleteTable(0, pSubitem->pTab);
  1913   1917       }
  1914         -    sqliteFree(pSrc->a[iFrom].zDatabase);
  1915         -    sqliteFree(pSrc->a[iFrom].zName);
  1916         -    sqliteFree(pSrc->a[iFrom].zAlias);
         1918  +    sqliteFree(pSubitem->zDatabase);
         1919  +    sqliteFree(pSubitem->zName);
         1920  +    sqliteFree(pSubitem->zAlias);
  1917   1921       if( nSubSrc>1 ){
  1918   1922         int extra = nSubSrc - 1;
  1919   1923         for(i=1; i<nSubSrc; i++){
  1920   1924           pSrc = sqlite3SrcListAppend(pSrc, 0, 0);
  1921   1925         }
  1922   1926         p->pSrc = pSrc;
  1923   1927         for(i=pSrc->nSrc-1; i-extra>=iFrom; i--){
................................................................................
  1968   1972       pWhere = 0;
  1969   1973     }
  1970   1974     if( subqueryIsAgg ){
  1971   1975       assert( p->pHaving==0 );
  1972   1976       p->pHaving = p->pWhere;
  1973   1977       p->pWhere = pWhere;
  1974   1978       substExpr(p->pHaving, iParent, pSub->pEList);
  1975         -    if( pSub->pHaving ){
  1976         -      Expr *pHaving = sqlite3ExprDup(pSub->pHaving);
  1977         -      if( p->pHaving ){
  1978         -        p->pHaving = sqlite3Expr(TK_AND, p->pHaving, pHaving, 0);
  1979         -      }else{
  1980         -        p->pHaving = pHaving;
  1981         -      }
  1982         -    }
         1979  +    p->pHaving = sqlite3ExprAnd(p->pHaving, sqlite3ExprDup(pSub->pHaving));
  1983   1980       assert( p->pGroupBy==0 );
  1984   1981       p->pGroupBy = sqlite3ExprListDup(pSub->pGroupBy);
  1985         -  }else if( p->pWhere==0 ){
  1986         -    p->pWhere = pWhere;
  1987   1982     }else{
  1988   1983       substExpr(p->pWhere, iParent, pSub->pEList);
  1989         -    if( pWhere ){
  1990         -      p->pWhere = sqlite3Expr(TK_AND, p->pWhere, pWhere, 0);
  1991         -    }
         1984  +    p->pWhere = sqlite3ExprAnd(p->pWhere, pWhere);
  1992   1985     }
  1993   1986   
  1994   1987     /* The flattened query is distinct if either the inner or the
  1995   1988     ** outer query is distinct. 
  1996   1989     */
  1997   1990     p->isDistinct = p->isDistinct || pSub->isDistinct;
  1998   1991   

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.317 2004/08/31 00:52:37 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.318 2004/09/01 03:06:35 drh Exp $
    15     15   */
    16     16   #ifndef _SQLITEINT_H_
    17     17   #define _SQLITEINT_H_
    18     18   
    19     19   #include "config.h"
    20     20   #include "sqlite3.h"
    21     21   #include "hash.h"
................................................................................
  1204   1204   void sqlite3SetNString(char **, ...);
  1205   1205   void sqlite3ErrorMsg(Parse*, const char*, ...);
  1206   1206   void sqlite3Dequote(char*);
  1207   1207   int sqlite3KeywordCode(const char*, int);
  1208   1208   int sqlite3RunParser(Parse*, const char*, char **);
  1209   1209   void sqlite3FinishCoding(Parse*);
  1210   1210   Expr *sqlite3Expr(int, Expr*, Expr*, Token*);
         1211  +Expr *sqlite3ExprAnd(Expr*, Expr*);
  1211   1212   void sqlite3ExprSpan(Expr*,Token*,Token*);
  1212   1213   Expr *sqlite3ExprFunction(ExprList*, Token*);
  1213   1214   void sqlite3ExprDelete(Expr*);
  1214   1215   ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*);
  1215   1216   void sqlite3ExprListDelete(ExprList*);
  1216   1217   int sqlite3Init(sqlite*, char**);
  1217   1218   int sqlite3InitCallback(void*, int, char**, char**);