/ Check-in [a167b71d]
Login

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

Overview
Comment:Split the IdList structure into IdList and SrcList. SrcList is used to represent a FROM clause and IdList is used for everything else. This change allows SrcList to grow to support outer joins without burdening the other uses of IdList. (CVS 584)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: a167b71d8c27e870bc3079c6132e483bffc83298
User & Date: drh 2002-05-24 02:04:33
Context
2002-05-24
02:14
Added tests for multi-column primary keys. (CVS 585) check-in: ffc49e56 user: drh tags: trunk
02:04
Split the IdList structure into IdList and SrcList. SrcList is used to represent a FROM clause and IdList is used for everything else. This change allows SrcList to grow to support outer joins without burdening the other uses of IdList. (CVS 584) check-in: a167b71d user: drh tags: trunk
2002-05-23
22:07
Change the names of the PushList and PopList opcodes to ListPush and ListPop so that they will appear together with the other List opcodes in the documentation. (CVS 583) check-in: c53b0b92 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

    21     21   **     COPY
    22     22   **     VACUUM
    23     23   **     BEGIN TRANSACTION
    24     24   **     COMMIT
    25     25   **     ROLLBACK
    26     26   **     PRAGMA
    27     27   **
    28         -** $Id: build.c,v 1.93 2002/05/22 21:27:03 drh Exp $
           28  +** $Id: build.c,v 1.94 2002/05/24 02:04:33 drh Exp $
    29     29   */
    30     30   #include "sqliteInt.h"
    31     31   #include <ctype.h>
    32     32   
    33     33   /*
    34     34   ** This routine is called after a single SQL statement has been
    35     35   ** parsed and we want to execute the VDBE code to implement 
................................................................................
  1530   1530       }else{
  1531   1531         sqliteDequote(*pz);
  1532   1532       }
  1533   1533     }
  1534   1534     pList->nId++;
  1535   1535     return pList;
  1536   1536   }
         1537  +
         1538  +/*
         1539  +** Append a new table name to the given SrcList.  Create a new SrcList if
         1540  +** need be.  A new entry is created in the SrcList even if pToken is NULL.
         1541  +**
         1542  +** A new SrcList is returned, or NULL if malloc() fails.
         1543  +*/
         1544  +SrcList *sqliteSrcListAppend(SrcList *pList, Token *pToken){
         1545  +  if( pList==0 ){
         1546  +    pList = sqliteMalloc( sizeof(IdList) );
         1547  +    if( pList==0 ) return 0;
         1548  +  }
         1549  +  if( (pList->nSrc & 7)==0 ){
         1550  +    struct SrcList_item *a;
         1551  +    a = sqliteRealloc(pList->a, (pList->nSrc+8)*sizeof(pList->a[0]) );
         1552  +    if( a==0 ){
         1553  +      sqliteSrcListDelete(pList);
         1554  +      return 0;
         1555  +    }
         1556  +    pList->a = a;
         1557  +  }
         1558  +  memset(&pList->a[pList->nSrc], 0, sizeof(pList->a[0]));
         1559  +  if( pToken ){
         1560  +    char **pz = &pList->a[pList->nSrc].zName;
         1561  +    sqliteSetNString(pz, pToken->z, pToken->n, 0);
         1562  +    if( *pz==0 ){
         1563  +      sqliteSrcListDelete(pList);
         1564  +      return 0;
         1565  +    }else{
         1566  +      sqliteDequote(*pz);
         1567  +    }
         1568  +  }
         1569  +  pList->nSrc++;
         1570  +  return pList;
         1571  +}
  1537   1572   
  1538   1573   /*
  1539   1574   ** Add an alias to the last identifier on the given identifier list.
  1540   1575   */
  1541         -void sqliteIdListAddAlias(IdList *pList, Token *pToken){
  1542         -  if( pList && pList->nId>0 ){
  1543         -    int i = pList->nId - 1;
         1576  +void sqliteSrcListAddAlias(SrcList *pList, Token *pToken){
         1577  +  if( pList && pList->nSrc>0 ){
         1578  +    int i = pList->nSrc - 1;
  1544   1579       sqliteSetNString(&pList->a[i].zAlias, pToken->z, pToken->n, 0);
  1545   1580       sqliteDequote(pList->a[i].zAlias);
  1546   1581     }
  1547   1582   }
  1548   1583   
  1549   1584   /*
  1550         -** Delete an entire IdList.
         1585  +** Delete an IdList.
  1551   1586   */
  1552   1587   void sqliteIdListDelete(IdList *pList){
  1553   1588     int i;
  1554   1589     if( pList==0 ) return;
  1555   1590     for(i=0; i<pList->nId; i++){
  1556   1591       sqliteFree(pList->a[i].zName);
         1592  +  }
         1593  +  sqliteFree(pList->a);
         1594  +  sqliteFree(pList);
         1595  +}
         1596  +
         1597  +/*
         1598  +** Delete an entire SrcList including all its substructure.
         1599  +*/
         1600  +void sqliteSrcListDelete(SrcList *pList){
         1601  +  int i;
         1602  +  if( pList==0 ) return;
         1603  +  for(i=0; i<pList->nSrc; i++){
         1604  +    sqliteFree(pList->a[i].zName);
  1557   1605       sqliteFree(pList->a[i].zAlias);
  1558   1606       if( pList->a[i].pTab && pList->a[i].pTab->isTransient ){
  1559   1607         sqliteDeleteTable(0, pList->a[i].pTab);
  1560   1608       }
  1561   1609       sqliteSelectDelete(pList->a[i].pSelect);
         1610  +    sqliteExprDelete(pList->a[i].pOn);
         1611  +    sqliteIdListDelete(pList->a[i].pUsing);
  1562   1612     }
  1563   1613     sqliteFree(pList->a);
  1564   1614     sqliteFree(pList);
  1565   1615   }
  1566   1616   
  1567   1617   /*
  1568   1618   ** The COPY command is for compatibility with PostgreSQL and specificially

Changes to src/delete.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 DELETE FROM statements.
    14     14   **
    15         -** $Id: delete.c,v 1.35 2002/05/23 12:50:18 drh Exp $
           15  +** $Id: delete.c,v 1.36 2002/05/24 02:04:33 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   
    20     20   /*
    21     21   ** Given a table name, find the corresponding table and make sure the
    22     22   ** table is writeable.  Generate an error and return NULL if not.  If
................................................................................
    39     39       return 0;      
    40     40     }
    41     41     return pTab;
    42     42   }
    43     43   
    44     44   /*
    45     45   ** Given a table name, check to make sure the table exists, is writable
    46         -** and is not a view.  If everything is OK, construct an IdList holding
    47         -** the table and return a pointer to the IdList.  The calling function
    48         -** is responsible for freeing the IdList when it has finished with it.
           46  +** and is not a view.  If everything is OK, construct an SrcList holding
           47  +** the table and return a pointer to the SrcList.  The calling function
           48  +** is responsible for freeing the SrcList when it has finished with it.
    49     49   ** If there is an error, leave a message on pParse->zErrMsg and return
    50     50   ** NULL.
    51     51   */
    52         -IdList *sqliteTableTokenToIdList(Parse *pParse, Token *pTableName){
           52  +SrcList *sqliteTableTokenToSrcList(Parse *pParse, Token *pTableName){
    53     53     Table *pTab;
    54         -  IdList *pTabList;
           54  +  SrcList *pTabList;
    55     55   
    56         -  pTabList = sqliteIdListAppend(0, pTableName);
           56  +  pTabList = sqliteSrcListAppend(0, pTableName);
    57     57     if( pTabList==0 ) return 0;
    58         -  assert( pTabList->nId==1 );
           58  +  assert( pTabList->nSrc==1 );
    59     59     pTab = sqliteTableNameToTable(pParse, pTabList->a[0].zName);
    60     60     if( pTab==0 ){
    61         -    sqliteIdListDelete(pTabList);
           61  +    sqliteSrcListDelete(pTabList);
    62     62       return 0;
    63     63     }
    64     64     pTabList->a[0].pTab = pTab;
    65     65     return pTabList;
    66     66   }
    67     67   
    68     68   /*
................................................................................
    72     72     Parse *pParse,         /* The parser context */
    73     73     Token *pTableName,     /* The table from which we should delete things */
    74     74     Expr *pWhere           /* The WHERE clause.  May be null */
    75     75   ){
    76     76     Vdbe *v;               /* The virtual database engine */
    77     77     Table *pTab;           /* The table from which records will be deleted */
    78     78     char *zTab;            /* Name of the table from which we are deleting */
    79         -  IdList *pTabList;      /* An ID list holding pTab and nothing else */
           79  +  SrcList *pTabList;     /* A fake FROM clause holding just pTab */
    80     80     int end, addr;         /* A couple addresses of generated code */
    81     81     int i;                 /* Loop counter */
    82     82     WhereInfo *pWInfo;     /* Information about the WHERE clause */
    83     83     Index *pIdx;           /* For looping over indices of the table */
    84     84     int base;              /* Index of the first available table cursor */
    85     85     sqlite *db;            /* Main database structure */
    86     86     int openOp;            /* Opcode used to open a cursor to the table */
................................................................................
   112    112         /* Just fire VIEW triggers */
   113    113         sqliteViewTriggers(pParse, pTab, pWhere, OE_Replace, 0);
   114    114         return;
   115    115       }
   116    116     }
   117    117   
   118    118     /* Locate the table which we want to delete.  This table has to be
   119         -  ** put in an IdList structure because some of the subroutines we
          119  +  ** put in an SrcList structure because some of the subroutines we
   120    120     ** will be calling are designed to work with multiple tables and expect
   121         -  ** an IdList* parameter instead of just a Table* parameter.
          121  +  ** an SrcList* parameter instead of just a Table* parameter.
   122    122     */
   123         -  pTabList = sqliteTableTokenToIdList(pParse, pTableName);
          123  +  pTabList = sqliteTableTokenToSrcList(pParse, pTableName);
   124    124     if( pTabList==0 ) goto delete_from_cleanup;
   125         -  assert( pTabList->nId==1 );
          125  +  assert( pTabList->nSrc==1 );
   126    126     pTab = pTabList->a[0].pTab;
   127    127     assert( pTab->pSelect==0 );  /* This table is not a view */
   128    128   
   129    129     /* Allocate a cursor used to store the old.* data for a trigger.
   130    130     */
   131    131     if( row_triggers_exist ){ 
   132    132       oldIdx = pParse->nTab++;
................................................................................
   297    297       sqliteVdbeAddOp(v, OP_ColumnCount, 1, 0);
   298    298       sqliteVdbeAddOp(v, OP_ColumnName, 0, 0);
   299    299       sqliteVdbeChangeP3(v, -1, "rows deleted", P3_STATIC);
   300    300       sqliteVdbeAddOp(v, OP_Callback, 1, 0);
   301    301     }
   302    302   
   303    303   delete_from_cleanup:
   304         -  sqliteIdListDelete(pTabList);
          304  +  sqliteSrcListDelete(pTabList);
   305    305     sqliteExprDelete(pWhere);
   306    306     return;
   307    307   }
   308    308   
   309    309   /*
   310    310   ** This routine generates VDBE code that causes a single row of a
   311    311   ** single table to be deleted.

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.62 2002/05/23 02:09:04 drh Exp $
           15  +** $Id: expr.c,v 1.63 2002/05/24 02:04:33 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    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
................................................................................
   151    151   ** be deleted (by being passed to their respective ...Delete() routines)
   152    152   ** without effecting the originals.
   153    153   **
   154    154   ** Note, however, that the Expr.token.z and Expr.span.z fields point to
   155    155   ** string space that is allocated separately from the expression tree
   156    156   ** itself.  These routines do NOT duplicate that string space.
   157    157   **
   158         -** The expression list and ID list return by sqliteExprListDup() and 
   159         -** sqliteIdListDup() can not be further expanded by subsequent calls
   160         -** to sqliteExprListAppend() or sqliteIdListAppend().
          158  +** The expression list, ID, and source lists return by sqliteExprListDup(),
          159  +** sqliteIdListDup(), and sqliteSrcListDup() can not be further expanded 
          160  +** by subsequent calls to sqlite*ListAppend() routines.
   161    161   **
   162         -** Any tables that the ID list might point to are not duplicated.
          162  +** Any tables that the SrcList might point to are not duplicated.
   163    163   */
   164    164   Expr *sqliteExprDup(Expr *p){
   165    165     Expr *pNew;
   166    166     if( p==0 ) return 0;
   167    167     pNew = sqliteMalloc( sizeof(*p) );
   168    168     if( pNew==0 ) return 0;
   169    169     pNew->op = p->op;
................................................................................
   191    191       pNew->a[i].pExpr = sqliteExprDup(p->a[i].pExpr);
   192    192       pNew->a[i].zName = sqliteStrDup(p->a[i].zName);
   193    193       pNew->a[i].sortOrder = p->a[i].sortOrder;
   194    194       pNew->a[i].isAgg = p->a[i].isAgg;
   195    195       pNew->a[i].done = 0;
   196    196     }
   197    197     return pNew;
          198  +}
          199  +SrcList *sqliteSrcListDup(SrcList *p){
          200  +  SrcList *pNew;
          201  +  int i;
          202  +  if( p==0 ) return 0;
          203  +  pNew = sqliteMalloc( sizeof(*pNew) );
          204  +  if( pNew==0 ) return 0;
          205  +  pNew->nSrc = p->nSrc;
          206  +  pNew->a = sqliteMalloc( p->nSrc*sizeof(p->a[0]) );
          207  +  if( pNew->a==0 ) return 0;
          208  +  for(i=0; i<p->nSrc; i++){
          209  +    pNew->a[i].zName = sqliteStrDup(p->a[i].zName);
          210  +    pNew->a[i].zAlias = sqliteStrDup(p->a[i].zAlias);
          211  +    pNew->a[i].jointype = p->a[i].jointype;
          212  +    pNew->a[i].pTab = 0;
          213  +    pNew->a[i].pSelect = sqliteSelectDup(p->a[i].pSelect);
          214  +    pNew->a[i].pOn = sqliteExprDup(p->a[i].pOn);
          215  +    pNew->a[i].pUsing = sqliteIdListDup(p->a[i].pUsing);
          216  +  }
          217  +  return pNew;
   198    218   }
   199    219   IdList *sqliteIdListDup(IdList *p){
   200    220     IdList *pNew;
   201    221     int i;
   202    222     if( p==0 ) return 0;
   203    223     pNew = sqliteMalloc( sizeof(*pNew) );
   204    224     if( pNew==0 ) return 0;
   205    225     pNew->nId = p->nId;
   206    226     pNew->a = sqliteMalloc( p->nId*sizeof(p->a[0]) );
   207    227     if( pNew->a==0 ) return 0;
   208    228     for(i=0; i<p->nId; i++){
   209    229       pNew->a[i].zName = sqliteStrDup(p->a[i].zName);
   210         -    pNew->a[i].zAlias = sqliteStrDup(p->a[i].zAlias);
   211    230       pNew->a[i].idx = p->a[i].idx;
   212         -    pNew->a[i].pTab = 0;
   213         -    pNew->a[i].pSelect = sqliteSelectDup(p->a[i].pSelect);
   214    231     }
   215    232     return pNew;
   216    233   }
   217    234   Select *sqliteSelectDup(Select *p){
   218    235     Select *pNew;
   219    236     if( p==0 ) return 0;
   220    237     pNew = sqliteMalloc( sizeof(*p) );
   221    238     if( pNew==0 ) return 0;
   222    239     pNew->isDistinct = p->isDistinct;
   223    240     pNew->pEList = sqliteExprListDup(p->pEList);
   224         -  pNew->pSrc = sqliteIdListDup(p->pSrc);
          241  +  pNew->pSrc = sqliteSrcListDup(p->pSrc);
   225    242     pNew->pWhere = sqliteExprDup(p->pWhere);
   226    243     pNew->pGroupBy = sqliteExprListDup(p->pGroupBy);
   227    244     pNew->pHaving = sqliteExprDup(p->pHaving);
   228    245     pNew->pOrderBy = sqliteExprListDup(p->pOrderBy);
   229    246     pNew->op = p->op;
   230    247     pNew->pPrior = sqliteSelectDup(p->pPrior);
   231    248     pNew->nLimit = p->nLimit;
................................................................................
   358    375   **
   359    376   ** Unknown columns or tables provoke an error.  The function returns
   360    377   ** the number of errors seen and leaves an error message on pParse->zErrMsg.
   361    378   */
   362    379   int sqliteExprResolveIds(
   363    380     Parse *pParse,     /* The parser context */
   364    381     int base,          /* VDBE cursor number for first entry in pTabList */
   365         -  IdList *pTabList,  /* List of tables used to resolve column names */
          382  +  SrcList *pTabList, /* List of tables used to resolve column names */
   366    383     ExprList *pEList,  /* List of expressions used to resolve "AS" */
   367    384     Expr *pExpr        /* The expression to be analyzed. */
   368    385   ){
   369    386     if( pExpr==0 || pTabList==0 ) return 0;
   370         -  assert( base+pTabList->nId<=pParse->nTab );
          387  +  assert( base+pTabList->nSrc<=pParse->nTab );
   371    388     switch( pExpr->op ){
   372    389       /* Double-quoted strings (ex: "abc") are used as identifiers if
   373    390       ** possible.  Otherwise they remain as strings.  Single-quoted
   374    391       ** strings (ex: 'abc') are always string literals.
   375    392       */
   376    393       case TK_STRING: {
   377    394         if( pExpr->token.z[0]=='\'' ) break;
................................................................................
   391    408         int cnt = 0;      /* Number of matches */
   392    409         int i;            /* Loop counter */
   393    410         char *z;
   394    411         assert( pExpr->token.z );
   395    412         z = sqliteStrNDup(pExpr->token.z, pExpr->token.n);
   396    413         sqliteDequote(z);
   397    414         if( z==0 ) return 1;
   398         -      for(i=0; i<pTabList->nId; i++){
          415  +      for(i=0; i<pTabList->nSrc; i++){
   399    416           int j;
   400    417           Table *pTab = pTabList->a[i].pTab;
   401    418           if( pTab==0 ) continue;
   402    419           assert( pTab->nCol>0 );
   403    420           for(j=0; j<pTab->nCol; j++){
   404    421             if( sqliteStrICmp(pTab->aCol[j].zName, z)==0 ){
   405    422               cnt++;
................................................................................
   426    443               pExpr->pLeft = sqliteExprDup(pEList->a[j].pExpr);
   427    444             }
   428    445           } 
   429    446         }
   430    447         if( cnt==0 && sqliteIsRowid(z) ){
   431    448           pExpr->iColumn = -1;
   432    449           pExpr->iTable = base;
   433         -        cnt = 1 + (pTabList->nId>1);
          450  +        cnt = 1 + (pTabList->nSrc>1);
   434    451           pExpr->op = TK_COLUMN;
   435    452         }
   436    453         sqliteFree(z);
   437    454         if( cnt==0 && pExpr->token.z[0]!='"' ){
   438    455           sqliteSetNString(&pParse->zErrMsg, "no such column: ", -1,  
   439    456             pExpr->token.z, pExpr->token.n, 0);
   440    457           pParse->nErr++;
................................................................................
   466    483           sqliteFree(zLeft);
   467    484           sqliteFree(zRight);
   468    485           return 1;
   469    486         }
   470    487         sqliteDequote(zLeft);
   471    488         sqliteDequote(zRight);
   472    489         pExpr->iTable = -1;
   473         -      for(i=0; i<pTabList->nId; i++){
          490  +      for(i=0; i<pTabList->nSrc; i++){
   474    491           int j;
   475    492           char *zTab;
   476    493           Table *pTab = pTabList->a[i].pTab;
   477    494           if( pTab==0 ) continue;
   478    495           assert( pTab->nCol>0 );
   479    496           if( pTabList->a[i].zAlias ){
   480    497             zTab = pTabList->a[i].zAlias;

Changes to src/insert.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 INSERT statements in SQLite.
    14     14   **
    15         -** $Id: insert.c,v 1.57 2002/05/21 12:56:43 drh Exp $
           15  +** $Id: insert.c,v 1.58 2002/05/24 02:04:33 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /*
    20     20   ** This routine is call to handle SQL of the following forms:
    21     21   **
    22     22   **    insert into TABLE (IDLIST) values(EXPRLIST)
................................................................................
   113    113       srcTab = pParse->nTab++;
   114    114       sqliteVdbeAddOp(v, OP_OpenTemp, srcTab, 0);
   115    115       rc = sqliteSelect(pParse, pSelect, SRT_Table, srcTab, 0,0,0);
   116    116       if( rc || pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup;
   117    117       assert( pSelect->pEList );
   118    118       nColumn = pSelect->pEList->nExpr;
   119    119     }else{
   120         -    IdList dummy;
          120  +    SrcList dummy;
   121    121       assert( pList!=0 );
   122    122       srcTab = -1;
   123    123       assert( pList );
   124    124       nColumn = pList->nExpr;
   125         -    dummy.nId = 0;
          125  +    dummy.nSrc = 0;
   126    126       for(i=0; i<nColumn; i++){
   127    127         if( sqliteExprResolveIds(pParse, 0, &dummy, 0, pList->a[i].pExpr) ){
   128    128           goto insert_cleanup;
   129    129         }
   130    130         if( sqliteExprCheck(pParse, pList->a[i].pExpr, 0, 0) ){
   131    131           goto insert_cleanup;
   132    132         }

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.67 2002/05/23 00:30:31 drh Exp $
           17  +** @(#) $Id: parse.y,v 1.68 2002/05/24 02:04:33 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);
................................................................................
    26     26   }
    27     27   %name sqliteParser
    28     28   %include {
    29     29   #include "sqliteInt.h"
    30     30   #include "parse.h"
    31     31   
    32     32   /*
    33         -** A structure for holding two integers
           33  +** An instance of this structure holds information about the
           34  +** LIMIT clause of a SELECT statement.
    34     35   */
    35         -struct twoint { int a,b; };
           36  +struct LimitVal {
           37  +  int limit;    /* The LIMIT value.  -1 if there is no limit */
           38  +  int offset;   /* The OFFSET.  0 if there is none */
           39  +};
    36     40   
    37     41   /*
    38         -** A structure for holding an integer and an IdList
           42  +** An instance of the following structure describes the event of a
           43  +** TRIGGER.  "a" is the event type, one of TK_UPDATE, TK_INSERT,
           44  +** TK_DELETE, or TK_INSTEAD.  If the event is of the form
           45  +**
           46  +**      UPDATE ON (a,b,c)
           47  +**
           48  +** Then the "b" IdList records the list "a,b,c".
    39     49   */
    40         -struct int_idlist { int a; IdList * b; };
           50  +struct TrigEvent { int a; IdList * b; };
    41     51   }
    42     52   
    43     53   // These are extra tokens used by the lexer but never seen by the
    44     54   // parser.  We put them in a rule so that the parser generator will
    45     55   // add them to the parse.h output file.
    46     56   //
    47     57   %nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
................................................................................
   236    246   %type multiselect_op {int}
   237    247   multiselect_op(A) ::= UNION.      {A = TK_UNION;}
   238    248   multiselect_op(A) ::= UNION ALL.  {A = TK_ALL;}
   239    249   multiselect_op(A) ::= INTERSECT.  {A = TK_INTERSECT;}
   240    250   multiselect_op(A) ::= EXCEPT.     {A = TK_EXCEPT;}
   241    251   oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y)
   242    252                    groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). {
   243         -  A = sqliteSelectNew(W,X,Y,P,Q,Z,D,L.a,L.b);
          253  +  A = sqliteSelectNew(W,X,Y,P,Q,Z,D,L.limit,L.offset);
   244    254   }
   245    255   
   246    256   // The "distinct" nonterminal is true (1) if the DISTINCT keyword is
   247    257   // present and false (0) if it is not.
   248    258   //
   249    259   %type distinct {int}
   250    260   distinct(A) ::= DISTINCT.   {A = 1;}
................................................................................
   272    282     Expr *pLeft = sqliteExpr(TK_ID, 0, 0, &X);
   273    283     A = sqliteExprListAppend(P, sqliteExpr(TK_DOT, pLeft, pRight, 0), 0);
   274    284   }
   275    285   as ::= .
   276    286   as ::= AS.
   277    287   
   278    288   
   279         -%type seltablist {IdList*}
   280         -%destructor seltablist {sqliteIdListDelete($$);}
   281         -%type stl_prefix {IdList*}
   282         -%destructor stl_prefix {sqliteIdListDelete($$);}
   283         -%type from {IdList*}
   284         -%destructor from {sqliteIdListDelete($$);}
          289  +%type seltablist {SrcList*}
          290  +%destructor seltablist {sqliteSrcListDelete($$);}
          291  +%type stl_prefix {SrcList*}
          292  +%destructor stl_prefix {sqliteSrcListDelete($$);}
          293  +%type from {SrcList*}
          294  +%destructor from {sqliteSrcListDelete($$);}
   285    295   
   286    296   from(A) ::= .                                 {A = sqliteMalloc(sizeof(*A));}
   287    297   from(A) ::= FROM seltablist(X).               {A = X;}
   288    298   stl_prefix(A) ::= seltablist(X) COMMA.        {A = X;}
   289    299   stl_prefix(A) ::= .                           {A = 0;}
   290         -seltablist(A) ::= stl_prefix(X) ids(Y).       {A = sqliteIdListAppend(X,&Y);}
          300  +seltablist(A) ::= stl_prefix(X) ids(Y).       {A = sqliteSrcListAppend(X,&Y);}
   291    301   seltablist(A) ::= stl_prefix(X) ids(Y) as ids(Z). {
   292         -  A = sqliteIdListAppend(X,&Y);
   293         -  sqliteIdListAddAlias(A,&Z);
          302  +  A = sqliteSrcListAppend(X,&Y);
          303  +  sqliteSrcListAddAlias(A,&Z);
   294    304   }
   295    305   seltablist(A) ::= stl_prefix(X) LP select(S) RP. {
   296         -  A = sqliteIdListAppend(X,0);
   297         -  A->a[A->nId-1].pSelect = S;
          306  +  A = sqliteSrcListAppend(X,0);
          307  +  A->a[A->nSrc-1].pSelect = S;
   298    308     if( S->pOrderBy ){
   299    309       sqliteExprListDelete(S->pOrderBy);
   300    310       S->pOrderBy = 0;
   301    311     }
   302    312   }
   303    313   seltablist(A) ::= stl_prefix(X) LP select(S) RP as ids(Z). {
   304         -  A = sqliteIdListAppend(X,0);
   305         -  A->a[A->nId-1].pSelect = S;
          314  +  A = sqliteSrcListAppend(X,0);
          315  +  A->a[A->nSrc-1].pSelect = S;
   306    316     if( S->pOrderBy ){
   307    317       sqliteExprListDelete(S->pOrderBy);
   308    318       S->pOrderBy = 0;
   309    319     }
   310         -  sqliteIdListAddAlias(A,&Z);
          320  +  sqliteSrcListAddAlias(A,&Z);
   311    321   }
   312    322   
   313    323   %type orderby_opt {ExprList*}
   314    324   %destructor orderby_opt {sqliteExprListDelete($$);}
   315    325   %type sortlist {ExprList*}
   316    326   %destructor sortlist {sqliteExprListDelete($$);}
   317    327   %type sortitem {Expr*}
................................................................................
   341    351   groupby_opt(A) ::= GROUP BY exprlist(X).  {A = X;}
   342    352   
   343    353   %type having_opt {Expr*}
   344    354   %destructor having_opt {sqliteExprDelete($$);}
   345    355   having_opt(A) ::= .                {A = 0;}
   346    356   having_opt(A) ::= HAVING expr(X).  {A = X;}
   347    357   
   348         -%type limit_opt {struct twoint}
   349         -limit_opt(A) ::= .                  {A.a = -1; A.b = 0;}
   350         -limit_opt(A) ::= LIMIT INTEGER(X).  {A.a = atoi(X.z); A.b = 0;}
          358  +%type limit_opt {struct LimitVal}
          359  +limit_opt(A) ::= .                  {A.limit = -1; A.offset = 0;}
          360  +limit_opt(A) ::= LIMIT INTEGER(X).  {A.limit = atoi(X.z); A.offset = 0;}
   351    361   limit_opt(A) ::= LIMIT INTEGER(X) limit_sep INTEGER(Y). 
   352         -                                    {A.a = atoi(X.z); A.b = atoi(Y.z);}
          362  +                                    {A.limit = atoi(X.z); A.offset = atoi(Y.z);}
   353    363   limit_sep ::= OFFSET.
   354    364   limit_sep ::= COMMA.
   355    365   
   356    366   /////////////////////////// The DELETE statement /////////////////////////////
   357    367   //
   358    368   cmd ::= DELETE FROM ids(X) where_opt(Y).
   359    369       {sqliteDeleteFrom(pParse, &X, Y);}
................................................................................
   651    661   
   652    662   %type trigger_time  {int}
   653    663   trigger_time(A) ::= BEFORE.      { A = TK_BEFORE; }
   654    664   trigger_time(A) ::= AFTER.       { A = TK_AFTER;  }
   655    665   trigger_time(A) ::= INSTEAD OF.  { A = TK_INSTEAD;}
   656    666   trigger_time(A) ::= .            { A = TK_BEFORE; }
   657    667   
   658         -%type trigger_event {struct int_idlist}
          668  +%type trigger_event {struct TrigEvent}
          669  +%destructor trigger_event {sqliteIdListDelete($$.b);}
   659    670   trigger_event(A) ::= DELETE. { A.a = TK_DELETE; A.b = 0; }
   660    671   trigger_event(A) ::= INSERT. { A.a = TK_INSERT; A.b = 0; }
   661    672   trigger_event(A) ::= UPDATE. { A.a = TK_UPDATE; A.b = 0;}
   662    673   trigger_event(A) ::= UPDATE OF inscollist(X). {A.a = TK_UPDATE; A.b = X; }
   663    674   
   664    675   %type foreach_clause {int}
   665    676   foreach_clause(A) ::= .                   { A = TK_ROW; }

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.81 2002/05/08 11:54:15 drh Exp $
           15  +** $Id: select.c,v 1.82 2002/05/24 02:04:33 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /*
    20     20   ** Allocate a new Select structure and return a pointer to that
    21     21   ** structure.
    22     22   */
    23     23   Select *sqliteSelectNew(
    24     24     ExprList *pEList,     /* which columns to include in the result */
    25         -  IdList *pSrc,         /* the FROM clause -- which tables to scan */
           25  +  SrcList *pSrc,        /* the FROM clause -- which tables to scan */
    26     26     Expr *pWhere,         /* the WHERE clause */
    27     27     ExprList *pGroupBy,   /* the GROUP BY clause */
    28     28     Expr *pHaving,        /* the HAVING clause */
    29     29     ExprList *pOrderBy,   /* the ORDER BY clause */
    30     30     int isDistinct,       /* true if the DISTINCT keyword is present */
    31     31     int nLimit,           /* LIMIT value.  -1 means not used */
    32     32     int nOffset           /* OFFSET value.  -1 means not used */
    33     33   ){
    34     34     Select *pNew;
    35     35     pNew = sqliteMalloc( sizeof(*pNew) );
    36     36     if( pNew==0 ){
    37     37       sqliteExprListDelete(pEList);
    38         -    sqliteIdListDelete(pSrc);
           38  +    sqliteSrcListDelete(pSrc);
    39     39       sqliteExprDelete(pWhere);
    40     40       sqliteExprListDelete(pGroupBy);
    41     41       sqliteExprDelete(pHaving);
    42     42       sqliteExprListDelete(pOrderBy);
    43     43     }else{
    44     44       pNew->pEList = pEList;
    45     45       pNew->pSrc = pSrc;
................................................................................
    57     57   
    58     58   /*
    59     59   ** Delete the given Select structure and all of its substructures.
    60     60   */
    61     61   void sqliteSelectDelete(Select *p){
    62     62     if( p==0 ) return;
    63     63     sqliteExprListDelete(p->pEList);
    64         -  sqliteIdListDelete(p->pSrc);
           64  +  sqliteSrcListDelete(p->pSrc);
    65     65     sqliteExprDelete(p->pWhere);
    66     66     sqliteExprListDelete(p->pGroupBy);
    67     67     sqliteExprDelete(p->pHaving);
    68     68     sqliteExprListDelete(p->pOrderBy);
    69     69     sqliteSelectDelete(p->pPrior);
    70     70     sqliteFree(p->zSelect);
    71     71     sqliteFree(p);
................................................................................
   230    230   ** Generate code that will tell the VDBE how many columns there
   231    231   ** are in the result and the name for each column.  This information
   232    232   ** is used to provide "argc" and "azCol[]" values in the callback.
   233    233   */
   234    234   static void generateColumnNames(
   235    235     Parse *pParse,      /* Parser context */
   236    236     int base,           /* VDBE cursor corresponding to first entry in pTabList */
   237         -  IdList *pTabList,   /* List of tables */
          237  +  SrcList *pTabList,  /* List of tables */
   238    238     ExprList *pEList    /* Expressions defining the result set */
   239    239   ){
   240    240     Vdbe *v = pParse->pVdbe;
   241    241     int i;
   242    242     if( pParse->colNamesSet || v==0 || sqlite_malloc_failed ) return;
   243    243     pParse->colNamesSet = 1;
   244    244     sqliteVdbeAddOp(v, OP_ColumnCount, pEList->nExpr, 0);
................................................................................
   261    261       }else if( p->op==TK_COLUMN && pTabList ){
   262    262         Table *pTab = pTabList->a[p->iTable - base].pTab;
   263    263         char *zCol;
   264    264         int iCol = p->iColumn;
   265    265         if( iCol<0 ) iCol = pTab->iPKey;
   266    266         assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
   267    267         zCol = iCol<0 ? "_ROWID_" : pTab->aCol[iCol].zName;
   268         -      if( pTabList->nId>1 || showFullNames ){
          268  +      if( pTabList->nSrc>1 || showFullNames ){
   269    269           char *zName = 0;
   270    270           char *zTab;
   271    271    
   272    272           zTab = pTabList->a[p->iTable - base].zAlias;
   273    273           if( showFullNames || zTab==0 ) zTab = pTab->zName;
   274    274           sqliteSetString(&zName, zTab, ".", zCol, 0);
   275    275           sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
................................................................................
   348    348     pTab->iPKey = -1;
   349    349     return pTab;
   350    350   }
   351    351   
   352    352   /*
   353    353   ** For the given SELECT statement, do two things.
   354    354   **
   355         -**    (1)  Fill in the pTabList->a[].pTab fields in the IdList that 
          355  +**    (1)  Fill in the pTabList->a[].pTab fields in the SrcList that 
   356    356   **         defines the set of tables that should be scanned. 
   357    357   **
   358    358   **    (2)  Scan the list of columns in the result set (pEList) looking
   359    359   **         for instances of the "*" operator or the TABLE.* operator.
   360    360   **         If found, expand each "*" to be every column in every table
   361    361   **         and TABLE.* to be every column in TABLE.
   362    362   **
   363    363   ** Return 0 on success.  If there are problems, leave an error message
   364    364   ** in pParse and return non-zero.
   365    365   */
   366    366   static int fillInColumnList(Parse *pParse, Select *p){
   367    367     int i, j, k, rc;
   368         -  IdList *pTabList;
          368  +  SrcList *pTabList;
   369    369     ExprList *pEList;
   370    370     Table *pTab;
   371    371   
   372    372     if( p==0 || p->pSrc==0 ) return 1;
   373    373     pTabList = p->pSrc;
   374    374     pEList = p->pEList;
   375    375   
   376    376     /* Look up every table in the table list.
   377    377     */
   378         -  for(i=0; i<pTabList->nId; i++){
          378  +  for(i=0; i<pTabList->nSrc; i++){
   379    379       if( pTabList->a[i].pTab ){
   380    380         /* This routine has run before!  No need to continue */
   381    381         return 0;
   382    382       }
   383    383       if( pTabList->a[i].zName==0 ){
   384    384         /* A sub-query in the FROM clause of a SELECT */
   385    385         assert( pTabList->a[i].pSelect!=0 );
................................................................................
   450    450           int tableSeen = 0;      /* Set to 1 when TABLE matches */
   451    451           Token *pName;           /* text of name of TABLE */
   452    452           if( pE->op==TK_DOT && pE->pLeft ){
   453    453             pName = &pE->pLeft->token;
   454    454           }else{
   455    455             pName = 0;
   456    456           }
   457         -        for(i=0; i<pTabList->nId; i++){
          457  +        for(i=0; i<pTabList->nSrc; i++){
   458    458             Table *pTab = pTabList->a[i].pTab;
   459    459             char *zTabName = pTabList->a[i].zAlias;
   460    460             if( zTabName==0 || zTabName[0]==0 ){ 
   461    461               zTabName = pTab->zName;
   462    462             }
   463    463             if( pName && (zTabName==0 || zTabName[0]==0 ||
   464    464                   sqliteStrNICmp(pName->z, zTabName, pName->n)!=0) ){
................................................................................
   507    507   **
   508    508   ** This routine is called on the Select structure that defines a
   509    509   ** VIEW in order to undo any bindings to tables.  This is necessary
   510    510   ** because those tables might be DROPed by a subsequent SQL command.
   511    511   */
   512    512   void sqliteSelectUnbind(Select *p){
   513    513     int i;
   514         -  IdList *pSrc = p->pSrc;
          514  +  SrcList *pSrc = p->pSrc;
   515    515     Table *pTab;
   516    516     if( p==0 ) return;
   517         -  for(i=0; i<pSrc->nId; i++){
          517  +  for(i=0; i<pSrc->nSrc; i++){
   518    518       if( (pTab = pSrc->a[i].pTab)!=0 ){
   519    519         if( pTab->isTransient ){
   520    520           sqliteDeleteTable(0, pTab);
   521    521           sqliteSelectDelete(pSrc->a[i].pSelect);
   522    522           pSrc->a[i].pSelect = 0;
   523    523         }
   524    524         pSrc->a[i].pTab = 0;
................................................................................
   928    928   ** If flattening is attempted this routine returns 1.
   929    929   **
   930    930   ** All of the expression analysis must occur on both the outer query and
   931    931   ** the subquery before this routine runs.
   932    932   */
   933    933   int flattenSubquery(Select *p, int iFrom, int isAgg, int subqueryIsAgg){
   934    934     Select *pSub;       /* The inner query or "subquery" */
   935         -  IdList *pSrc;       /* The FROM clause of the outer query */
   936         -  IdList *pSubSrc;    /* The FROM clause of the subquery */
          935  +  SrcList *pSrc;      /* The FROM clause of the outer query */
          936  +  SrcList *pSubSrc;   /* The FROM clause of the subquery */
   937    937     ExprList *pList;    /* The result set of the outer query */
   938    938     int i;
   939    939     int iParent, iSub;
   940    940     Expr *pWhere;
   941    941   
   942    942     /* Check to see if flattening is permitted.  Return 0 if not.
   943    943     */
   944    944     if( p==0 ) return 0;
   945    945     pSrc = p->pSrc;
   946         -  assert( pSrc && iFrom>=0 && iFrom<pSrc->nId );
          946  +  assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
   947    947     pSub = pSrc->a[iFrom].pSelect;
   948    948     assert( pSub!=0 );
   949    949     if( isAgg && subqueryIsAgg ) return 0;
   950         -  if( subqueryIsAgg && pSrc->nId>1 ) return 0;
          950  +  if( subqueryIsAgg && pSrc->nSrc>1 ) return 0;
   951    951     pSubSrc = pSub->pSrc;
   952    952     assert( pSubSrc );
   953         -  if( pSubSrc->nId!=1 ) return 0;
   954         -  if( pSub->isDistinct && pSrc->nId>1 ) return 0;
          953  +  if( pSubSrc->nSrc!=1 ) return 0;
          954  +  if( pSub->isDistinct && pSrc->nSrc>1 ) return 0;
   955    955     if( pSub->isDistinct && isAgg ) return 0;
   956    956     if( p->isDistinct && subqueryIsAgg ) return 0;
   957    957   
   958    958     /* If we reach this point, it means flattening is permitted for the
   959    959     ** i-th entry of the FROM clause in the outer query.
   960    960     */
   961    961     iParent = p->base + iFrom;
................................................................................
  1055   1055     ExprList eList;
  1056   1056     struct ExprList_item eListItem;
  1057   1057   
  1058   1058     /* Check to see if this query is a simple min() or max() query.  Return
  1059   1059     ** zero if it is  not.
  1060   1060     */
  1061   1061     if( p->pGroupBy || p->pHaving || p->pWhere ) return 0;
  1062         -  if( p->pSrc->nId!=1 ) return 0;
         1062  +  if( p->pSrc->nSrc!=1 ) return 0;
  1063   1063     if( p->pEList->nExpr!=1 ) return 0;
  1064   1064     pExpr = p->pEList->a[0].pExpr;
  1065   1065     if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
  1066   1066     if( pExpr->pList==0 || pExpr->pList->nExpr!=1 ) return 0;
  1067   1067     if( pExpr->token.n!=3 ) return 0;
  1068   1068     if( sqliteStrNICmp(pExpr->token.z,"min",3)==0 ){
  1069   1069       seekOp = OP_Rewind;
................................................................................
  1180   1180     int *pParentAgg        /* True if pParent uses aggregate functions */
  1181   1181   ){
  1182   1182     int i;
  1183   1183     WhereInfo *pWInfo;
  1184   1184     Vdbe *v;
  1185   1185     int isAgg = 0;         /* True for select lists like "count(*)" */
  1186   1186     ExprList *pEList;      /* List of columns to extract. */
  1187         -  IdList *pTabList;      /* List of tables to select from */
         1187  +  SrcList *pTabList;     /* List of tables to select from */
  1188   1188     Expr *pWhere;          /* The WHERE clause.  May be NULL */
  1189   1189     ExprList *pOrderBy;    /* The ORDER BY clause.  May be NULL */
  1190   1190     ExprList *pGroupBy;    /* The GROUP BY clause.  May be NULL */
  1191   1191     Expr *pHaving;         /* The HAVING clause.  May be NULL */
  1192   1192     int isDistinct;        /* True if the DISTINCT keyword is present */
  1193   1193     int distinct;          /* Table to use for the distinct set */
  1194   1194     int base;              /* First cursor available for use */
................................................................................
  1212   1212     isDistinct = p->isDistinct;
  1213   1213   
  1214   1214     /* Allocate a block of VDBE cursors, one for each table in the FROM clause.
  1215   1215     ** The WHERE processing requires that the cursors for the tables in the
  1216   1216     ** FROM clause be consecutive.
  1217   1217     */
  1218   1218     base = p->base = pParse->nTab;
  1219         -  pParse->nTab += pTabList->nId;
         1219  +  pParse->nTab += pTabList->nSrc;
  1220   1220   
  1221   1221     /* 
  1222   1222     ** Do not even attempt to generate any code if we have already seen
  1223   1223     ** errors before this routine starts.
  1224   1224     */
  1225   1225     if( pParse->nErr>0 ) goto select_end;
  1226   1226   
................................................................................
  1347   1347     }else{
  1348   1348       if( p->nOffset<0 ) p->nOffset = 0;
  1349   1349       sqliteVdbeAddOp(v, OP_Limit, p->nLimit, p->nOffset);
  1350   1350     }
  1351   1351   
  1352   1352     /* Generate code for all sub-queries in the FROM clause
  1353   1353     */
  1354         -  for(i=0; i<pTabList->nId; i++){
         1354  +  for(i=0; i<pTabList->nSrc; i++){
  1355   1355       if( pTabList->a[i].pSelect==0 ) continue;
  1356   1356       sqliteSelect(pParse, pTabList->a[i].pSelect, SRT_TempTable, base+i,
  1357   1357                    p, i, &isAgg);
  1358   1358       pTabList = p->pSrc;
  1359   1359       pWhere = p->pWhere;
  1360   1360       if( eDest==SRT_Callback ){
  1361   1361         pOrderBy = p->pOrderBy;

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.112 2002/05/21 13:18:26 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.113 2002/05/24 02:04:33 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>
................................................................................
   135    135   typedef struct Index Index;
   136    136   typedef struct Instruction Instruction;
   137    137   typedef struct Expr Expr;
   138    138   typedef struct ExprList ExprList;
   139    139   typedef struct Parse Parse;
   140    140   typedef struct Token Token;
   141    141   typedef struct IdList IdList;
          142  +typedef struct SrcList SrcList;
   142    143   typedef struct WhereInfo WhereInfo;
   143    144   typedef struct WhereLevel WhereLevel;
   144    145   typedef struct Select Select;
   145    146   typedef struct AggExpr AggExpr;
   146    147   typedef struct FuncDef FuncDef;
   147    148   typedef struct Trigger Trigger;
   148    149   typedef struct TriggerStep TriggerStep;
................................................................................
   396    397   };
   397    398   
   398    399   /*
   399    400   ** A list of expressions.  Each expression may optionally have a
   400    401   ** name.  An expr/name combination can be used in several ways, such
   401    402   ** as the list of "expr AS ID" fields following a "SELECT" or in the
   402    403   ** list of "ID = expr" items in an UPDATE.  A list of expressions can
   403         -** also be used as the argument to a function, in which case the azName
          404  +** also be used as the argument to a function, in which case the a.zName
   404    405   ** field is not used.
   405    406   */
   406    407   struct ExprList {
   407    408     int nExpr;             /* Number of expressions on the list */
   408    409     struct ExprList_item {
   409    410       Expr *pExpr;           /* The list of expressions */
   410    411       char *zName;           /* Token associated with this expression */
................................................................................
   411    412       char sortOrder;        /* 1 for DESC or 0 for ASC */
   412    413       char isAgg;            /* True if this is an aggregate like count(*) */
   413    414       char done;             /* A flag to indicate when processing is finished */
   414    415     } *a;                  /* One entry for each expression */
   415    416   };
   416    417   
   417    418   /*
   418         -** A list of identifiers.
          419  +** An instance of this structure can hold a simple list of identifiers,
          420  +** such as the list "a,b,c" in the following statements:
          421  +**
          422  +**      INSERT INTO t(a,b,c) VALUES ...;
          423  +**      CREATE INDEX idx ON t(a,b,c);
          424  +**      CREATE TRIGGER trig BEFORE UPDATE ON t(a,b,c) ...;
          425  +**
          426  +** The IdList.a.idx field is used when the IdList represents the list of
          427  +** column names after a table name in an INSERT statement.  In the statement
          428  +**
          429  +**     INSERT INTO t(a,b,c) ...
          430  +**
          431  +** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
   419    432   */
   420    433   struct IdList {
   421    434     int nId;         /* Number of identifiers on the list */
   422    435     struct IdList_item {
   423         -    char *zName;      /* Text of the identifier. */
   424         -    char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
          436  +    char *zName;      /* Name of the identifier */
   425    437       int idx;          /* Index in some Table.aCol[] of a column named zName */
          438  +  } *a;
          439  +};
          440  +
          441  +/*
          442  +** The following structure describes the FROM clause of a SELECT statement.
          443  +** Each table or subquery in the FROM clause is a separate element of
          444  +** the SrcList.a[] array.
          445  +*/
          446  +struct SrcList {
          447  +  int nSrc;        /* Number of tables or subqueries in the FROM clause */
          448  +  struct SrcList_item {
          449  +    char *zName;      /* Name of the table */
          450  +    char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
   426    451       Table *pTab;      /* An SQL table corresponding to zName */
   427    452       Select *pSelect;  /* A SELECT statement used in place of a table name */
          453  +    int jointype;     /* Type of join between this table and the next */
          454  +    Expr *pOn;        /* The ON clause of a join */
          455  +    IdList *pUsing;   /* The USING clause of a join */
   428    456     } *a;            /* One entry for each identifier on the list */
   429    457   };
   430    458   
   431    459   /*
   432    460   ** For each nested loop in a WHERE clause implementation, the WhereInfo
   433    461   ** structure contains a single instance of this structure.  This structure
   434    462   ** is intended to be private the the where.c module and should not be
................................................................................
   449    477   ** first part does the start of the WHERE loop and the second
   450    478   ** half does the tail of the WHERE loop.  An instance of
   451    479   ** this structure is returned by the first half and passed
   452    480   ** into the second half to give some continuity.
   453    481   */
   454    482   struct WhereInfo {
   455    483     Parse *pParse;
   456         -  IdList *pTabList;    /* List of tables in the join */
          484  +  SrcList *pTabList;   /* List of tables in the join */
   457    485     int iContinue;       /* Jump here to continue with next record */
   458    486     int iBreak;          /* Jump here to break out of the loop */
   459    487     int base;            /* Index of first Open opcode */
   460    488     int nLevel;          /* Number of nested loop */
   461    489     int savedNTab;       /* Value of pParse->nTab before WhereBegin() */
   462    490     int peakNTab;        /* Value of pParse->nTab after WhereBegin() */
   463    491     WhereLevel a[1];     /* Information about each nest loop in the WHERE */
................................................................................
   474    502   ** a VIEW) we have to make a copy of the input string so that the nodes
   475    503   ** of the expression tree will have something to point to.  zSelect is used
   476    504   ** to hold that copy.
   477    505   */
   478    506   struct Select {
   479    507     int isDistinct;        /* True if the DISTINCT keyword is present */
   480    508     ExprList *pEList;      /* The fields of the result */
   481         -  IdList *pSrc;          /* The FROM clause */
          509  +  SrcList *pSrc;         /* The FROM clause */
   482    510     Expr *pWhere;          /* The WHERE clause */
   483    511     ExprList *pGroupBy;    /* The GROUP BY clause */
   484    512     Expr *pHaving;         /* The HAVING clause */
   485    513     ExprList *pOrderBy;    /* The ORDER BY clause */
   486    514     int op;                /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
   487    515     Select *pPrior;        /* Prior select in a compound select statement */
   488    516     int nLimit, nOffset;   /* LIMIT and OFFSET values.  -1 means not used */
................................................................................
   565    593    * Each trigger present in the database schema is stored as an instance of
   566    594    * struct Trigger. 
   567    595    *
   568    596    * Pointers to instances of struct Trigger are stored in two ways.
   569    597    * 1. In the "trigHash" hash table (part of the sqlite* that represents the 
   570    598    *    database). This allows Trigger structures to be retrieved by name.
   571    599    * 2. All triggers associated with a single table form a linked list, using the
   572         - *    pNext member of struct Trigger. A pointer to the first element of the linked
   573         - *    list is stored as the "pTrigger" member of the associated struct Table.
          600  + *    pNext member of struct Trigger. A pointer to the first element of the
          601  + *    linked list is stored as the "pTrigger" member of the associated
          602  + *    struct Table.
   574    603    *
   575    604    * The "strings" member of struct Trigger contains a pointer to the memory 
   576    605    * referenced by the various Token structures referenced indirectly by the
   577    606    * "pWhen", "pColumns" and "step_list" members. (ie. the memory allocated for
   578    607    * use in conjunction with the sqliteExprMoveStrings() etc. interface).
   579    608    *
   580         - * The "step_list" member points to the first element of a linked list containing
   581         - * the SQL statements specified as the trigger program.
          609  + * The "step_list" member points to the first element of a linked list
          610  + * containing the SQL statements specified as the trigger program.
   582    611    *
   583    612    * When a trigger is initially created, the "isCommit" member is set to FALSE.
   584    613    * When a transaction is rolled back, any Trigger structures with "isCommit" set
   585    614    * to FALSE are deleted by the logic in sqliteRollbackInternalChanges(). When
   586    615    * a transaction is commited, the "isCommit" member is set to TRUE for any
   587    616    * Trigger structures for which it is FALSE.
   588    617    *
   589    618    * When a trigger is dropped, using the sqliteDropTrigger() interfaced, it is 
   590         - * removed from the trigHash hash table and added to the trigDrop hash table. If 
   591         - * the transaction is rolled back, the trigger is re-added into the trigHash
          619  + * removed from the trigHash hash table and added to the trigDrop hash table.
          620  + * If the transaction is rolled back, the trigger is re-added into the trigHash
   592    621    * hash table (and hence the database schema). If the transaction is commited,
   593    622    * then the Trigger structure is deleted permanently.
   594    623    */
   595    624   struct Trigger {
   596    625     char *name;             /* The name of the trigger                        */
   597    626     char *table;            /* The table or view to which the trigger applies */
   598    627     int op;                 /* One of TK_DELETE, TK_UPDATE, TK_INSERT         */
................................................................................
   625    654    * orconf    -> stores the ON CONFLICT algorithm
   626    655    * pSelect   -> If this is an INSERT INTO ... SELECT ... statement, then
   627    656    *              this stores a pointer to the SELECT statement. Otherwise NULL.
   628    657    * target    -> A token holding the name of the table to insert into.
   629    658    * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
   630    659    *              this stores values to be inserted. Otherwise NULL.
   631    660    * pIdList   -> If this is an INSERT INTO ... (<column-names>) VALUES ... 
   632         - *              statement, then this stores the column-names to be inserted into.
          661  + *              statement, then this stores the column-names to be
          662  + *              inserted into.
   633    663    *
   634    664    * (op == TK_DELETE)
   635    665    * target    -> A token holding the name of the table to delete from.
   636    666    * pWhere    -> The WHERE clause of the DELETE statement if one is specified.
   637    667    *              Otherwise NULL.
   638    668    * 
   639    669    * (op == TK_UPDATE)
   640    670    * target    -> A token holding the name of the table to update rows of.
   641    671    * pWhere    -> The WHERE clause of the UPDATE statement if one is specified.
   642    672    *              Otherwise NULL.
   643    673    * pExprList -> A list of the columns to update and the expressions to update
   644         - *              them to. See sqliteUpdate() documentation of "pChanges" argument.
          674  + *              them to. See sqliteUpdate() documentation of "pChanges"
          675  + *              argument.
   645    676    * 
   646    677    */
   647    678   struct TriggerStep {
   648    679     int op;              /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
   649    680     int orconf;          /* OE_Rollback etc. */
   650    681   
   651    682     Select *pSelect;     /* Valid for SELECT and sometimes 
................................................................................
   751    782   void sqliteCreateView(Parse*,Token*,Token*,Select*);
   752    783   int sqliteViewGetColumnNames(Parse*,Table*);
   753    784   void sqliteViewResetAll(sqlite*);
   754    785   void sqliteDropTable(Parse*, Token*, int);
   755    786   void sqliteDeleteTable(sqlite*, Table*);
   756    787   void sqliteInsert(Parse*, Token*, ExprList*, Select*, IdList*, int);
   757    788   IdList *sqliteIdListAppend(IdList*, Token*);
   758         -void sqliteIdListAddAlias(IdList*, Token*);
          789  +SrcList *sqliteSrcListAppend(SrcList*, Token*);
          790  +void sqliteSrcListAddAlias(SrcList*, Token*);
   759    791   void sqliteIdListDelete(IdList*);
          792  +void sqliteSrcListDelete(SrcList*);
   760    793   void sqliteCreateIndex(Parse*, Token*, Token*, IdList*, int, Token*, Token*);
   761    794   void sqliteDropIndex(Parse*, Token*);
   762    795   int sqliteSelect(Parse*, Select*, int, int, Select*, int, int*);
   763         -Select *sqliteSelectNew(ExprList*,IdList*,Expr*,ExprList*,Expr*,ExprList*,
          796  +Select *sqliteSelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*,
   764    797                           int,int,int);
   765    798   void sqliteSelectDelete(Select*);
   766    799   void sqliteSelectUnbind(Select*);
   767    800   Table *sqliteTableNameToTable(Parse*, const char*);
   768         -IdList *sqliteTableTokenToIdList(Parse*, Token*);
          801  +SrcList *sqliteTableTokenToSrcList(Parse*, Token*);
   769    802   void sqliteDeleteFrom(Parse*, Token*, Expr*);
   770    803   void sqliteUpdate(Parse*, Token*, ExprList*, Expr*, int);
   771         -WhereInfo *sqliteWhereBegin(Parse*, int, IdList*, Expr*, int);
          804  +WhereInfo *sqliteWhereBegin(Parse*, int, SrcList*, Expr*, int);
   772    805   void sqliteWhereEnd(WhereInfo*);
   773    806   void sqliteExprCode(Parse*, Expr*);
   774    807   void sqliteExprIfTrue(Parse*, Expr*, int);
   775    808   void sqliteExprIfFalse(Parse*, Expr*, int);
   776    809   Table *sqliteFindTable(sqlite*,const char*);
   777    810   Index *sqliteFindIndex(sqlite*,const char*);
   778    811   void sqliteUnlinkAndDeleteIndex(sqlite*,Index*);
................................................................................
   780    813   void sqliteVacuum(Parse*, Token*);
   781    814   int sqliteGlobCompare(const unsigned char*,const unsigned char*);
   782    815   int sqliteLikeCompare(const unsigned char*,const unsigned char*);
   783    816   char *sqliteTableNameFromToken(Token*);
   784    817   int sqliteExprCheck(Parse*, Expr*, int, int*);
   785    818   int sqliteExprCompare(Expr*, Expr*);
   786    819   int sqliteFuncId(Token*);
   787         -int sqliteExprResolveIds(Parse*, int, IdList*, ExprList*, Expr*);
          820  +int sqliteExprResolveIds(Parse*, int, SrcList*, ExprList*, Expr*);
   788    821   int sqliteExprAnalyzeAggregates(Parse*, Expr*);
   789    822   Vdbe *sqliteGetVdbe(Parse*);
   790    823   int sqliteRandomByte(void);
   791    824   int sqliteRandomInteger(void);
   792    825   void sqliteBeginTransaction(Parse*, int);
   793    826   void sqliteCommitTransaction(Parse*);
   794    827   void sqliteRollbackTransaction(Parse*);
................................................................................
   801    834   void sqliteBeginWriteOperation(Parse*, int);
   802    835   void sqliteEndWriteOperation(Parse*);
   803    836   void sqliteExprMoveStrings(Expr*, int);
   804    837   void sqliteExprListMoveStrings(ExprList*, int);
   805    838   void sqliteSelectMoveStrings(Select*, int);
   806    839   Expr *sqliteExprDup(Expr*);
   807    840   ExprList *sqliteExprListDup(ExprList*);
          841  +SrcList *sqliteSrcListDup(SrcList*);
   808    842   IdList *sqliteIdListDup(IdList*);
   809    843   Select *sqliteSelectDup(Select*);
   810    844   FuncDef *sqliteFindFunction(sqlite*,const char*,int,int,int);
   811    845   void sqliteRegisterBuildinFunctions(sqlite*);
   812    846   int sqliteSafetyOn(sqlite*);
   813    847   int sqliteSafetyOff(sqlite*);
   814    848   int sqliteSafetyCheck(sqlite*);

Changes to src/trigger.c.

   567    567             !checkColumnOverLap(pTrigger->pColumns, pChanges) ){
   568    568           fire_this = 0;
   569    569         }
   570    570       }
   571    571   
   572    572       if( fire_this && (pTriggerStack = sqliteMalloc(sizeof(TriggerStack)))!=0 ){
   573    573         int endTrigger;
   574         -      IdList dummyTablist;
          574  +      SrcList dummyTablist;
   575    575         Expr * whenExpr;
   576    576   
   577         -      dummyTablist.nId = 0;
          577  +      dummyTablist.nSrc = 0;
   578    578         dummyTablist.a = 0;
   579    579   
   580    580         /* Push an entry on to the trigger stack */
   581    581         pTriggerStack->pTrigger = pTrigger;
   582    582         pTriggerStack->newIdx = newIdx;
   583    583         pTriggerStack->oldIdx = oldIdx;
   584    584         pTriggerStack->pTab = pTab;
................................................................................
   641    641     assert(pTab->pSelect);
   642    642   
   643    643     tblNameToken.z = pTab->zName;
   644    644     tblNameToken.n = strlen(pTab->zName);
   645    645   
   646    646     theSelect.isDistinct = 0;
   647    647     theSelect.pEList = sqliteExprListAppend(0, sqliteExpr(TK_ALL, 0, 0, 0), 0);
   648         -  theSelect.pSrc   = sqliteIdListAppend(0, &tblNameToken);
          648  +  theSelect.pSrc   = sqliteSrcListAppend(0, &tblNameToken);
   649    649     theSelect.pWhere = pWhere;    pWhere = 0;
   650    650     theSelect.pGroupBy = 0;
   651    651     theSelect.pHaving = 0;
   652    652     theSelect.pOrderBy = 0;
   653    653     theSelect.op = TK_SELECT; /* ?? */
   654    654     theSelect.pPrior = 0;
   655    655     theSelect.nLimit = -1;
................................................................................
   746    746     sqliteEndWriteOperation(pParse);
   747    747   
   748    748   trigger_cleanup:
   749    749     sqliteFree(aXRef);
   750    750     sqliteExprListDelete(pChanges);
   751    751     sqliteExprDelete(pWhere);
   752    752     sqliteExprListDelete(theSelect.pEList);
   753         -  sqliteIdListDelete(theSelect.pSrc);
          753  +  sqliteSrcListDelete(theSelect.pSrc);
   754    754     sqliteExprDelete(theSelect.pWhere);
   755    755     return;
   756    756   }

Changes to src/update.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 UPDATE statements.
    14     14   **
    15         -** $Id: update.c,v 1.42 2002/05/23 22:07:03 drh Exp $
           15  +** $Id: update.c,v 1.43 2002/05/24 02:04:34 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /*
    20     20   ** Process an UPDATE statement.
    21     21   */
    22     22   void sqliteUpdate(
................................................................................
    24     24     Token *pTableName,     /* The table in which we should change things */
    25     25     ExprList *pChanges,    /* Things to be changed */
    26     26     Expr *pWhere,          /* The WHERE clause.  May be null */
    27     27     int onError            /* How to handle constraint errors */
    28     28   ){
    29     29     int i, j;              /* Loop counters */
    30     30     Table *pTab;           /* The table to be updated */
    31         -  IdList *pTabList = 0;  /* List containing only pTab */
           31  +  SrcList *pTabList = 0; /* Fake FROM clause containing only pTab */
    32     32     int addr;              /* VDBE instruction address of the start of the loop */
    33     33     WhereInfo *pWInfo;     /* Information about the WHERE clause */
    34     34     Vdbe *v;               /* The virtual database engine */
    35     35     Index *pIdx;           /* For looping over indices */
    36     36     int nIdx;              /* Number of indices that need updating */
    37     37     int nIdxTotal;         /* Total number of indices */
    38     38     int base;              /* Index of first available table cursor */
................................................................................
    76     76           sqliteViewTriggers(pParse, pTab, pWhere, onError, pChanges);
    77     77           return;
    78     78         }
    79     79       }
    80     80     }
    81     81   
    82     82     /* Locate the table which we want to update.  This table has to be
    83         -  ** put in an IdList structure because some of the subroutines we
           83  +  ** put in an SrcList structure because some of the subroutines we
    84     84     ** will be calling are designed to work with multiple tables and expect
    85         -  ** an IdList* parameter instead of just a Table* parameter.
           85  +  ** an SrcList* parameter instead of just a Table* parameter.
    86     86     */
    87         -  pTabList = sqliteTableTokenToIdList(pParse, pTableName);
           87  +  pTabList = sqliteTableTokenToSrcList(pParse, pTableName);
    88     88     if( pTabList==0 ) goto update_cleanup;
    89     89     pTab = pTabList->a[0].pTab;
    90     90     assert( pTab->pSelect==0 );  /* This table is not a VIEW */
    91     91     aXRef = sqliteMalloc( sizeof(int) * pTab->nCol );
    92     92     if( aXRef==0 ) goto update_cleanup;
    93     93     for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
    94     94   
................................................................................
   387    387       sqliteVdbeChangeP3(v, -1, "rows updated", P3_STATIC);
   388    388       sqliteVdbeAddOp(v, OP_Callback, 1, 0);
   389    389     }
   390    390   
   391    391   update_cleanup:
   392    392     sqliteFree(apIdx);
   393    393     sqliteFree(aXRef);
   394         -  sqliteIdListDelete(pTabList);
          394  +  sqliteSrcListDelete(pTabList);
   395    395     sqliteExprListDelete(pChanges);
   396    396     sqliteExprDelete(pWhere);
   397    397     return;
   398    398   }

Changes to src/vdbe.c.

    26     26   ** type to the other occurs as necessary.
    27     27   ** 
    28     28   ** Most of the code in this file is taken up by the sqliteVdbeExec()
    29     29   ** function which does the work of interpreting a VDBE program.
    30     30   ** But other routines are also provided to help in building up
    31     31   ** a program instruction by instruction.
    32     32   **
    33         -** $Id: vdbe.c,v 1.146 2002/05/23 22:07:03 drh Exp $
           33  +** $Id: vdbe.c,v 1.147 2002/05/24 02:04:34 drh Exp $
    34     34   */
    35     35   #include "sqliteInt.h"
    36     36   #include <ctype.h>
    37     37   
    38     38   /*
    39     39   ** The following global variable is incremented every time a cursor
    40     40   ** moves, either by the OP_MoveTo or the OP_Next opcode.  The test
................................................................................
   229    229     int *aLabel;        /* Space to hold the labels */
   230    230     int tos;            /* Index of top of stack */
   231    231     int nStackAlloc;    /* Size of the stack */
   232    232     Stack *aStack;      /* The operand stack, except string values */
   233    233     char **zStack;      /* Text or binary values of the stack */
   234    234     char **azColName;   /* Becomes the 4th parameter to callbacks */
   235    235     int nCursor;        /* Number of slots in aCsr[] */
   236         -  Cursor *aCsr;       /* On element of this array for each open cursor */
          236  +  Cursor *aCsr;       /* One element of this array for each open cursor */
   237    237     Keylist *pList;     /* A list of ROWIDs */
   238    238     Sorter *pSort;      /* A linked list of objects to be sorted */
   239    239     FILE *pFile;        /* At most one open file handler */
   240    240     int nField;         /* Number of file fields */
   241    241     char **azField;     /* Data for each file field */
   242    242     char *zLine;        /* A single line from the input file */
   243    243     int nLineAlloc;     /* Number of spaces allocated for zLine */
................................................................................
  3819   3819       p->pList = 0;
  3820   3820     }
  3821   3821     break;
  3822   3822   }
  3823   3823   
  3824   3824   /* Opcode: ListPush * * * 
  3825   3825   **
  3826         -** Save the current Vdbe list such that it can be restored by a PopList 
         3826  +** Save the current Vdbe list such that it can be restored by a ListPop
  3827   3827   ** opcode. The list is empty after this is executed.
  3828   3828   */
  3829   3829   case OP_ListPush: {
  3830   3830     p->keylistStackDepth++;
  3831   3831     assert(p->keylistStackDepth > 0);
  3832   3832     p->keylistStack = sqliteRealloc(p->keylistStack, 
  3833   3833             sizeof(Keylist *) * p->keylistStackDepth);
................................................................................
  3834   3834     p->keylistStack[p->keylistStackDepth - 1] = p->pList;
  3835   3835     p->pList = 0;
  3836   3836     break;
  3837   3837   }
  3838   3838   
  3839   3839   /* Opcode: ListPop * * * 
  3840   3840   **
  3841         -** Restore the Vdbe list to the state it was in when PushList was last
         3841  +** Restore the Vdbe list to the state it was in when ListPush was last
  3842   3842   ** executed.
  3843   3843   */
  3844   3844   case OP_ListPop: {
  3845   3845     assert(p->keylistStackDepth > 0);
  3846   3846     p->keylistStackDepth--;
  3847   3847     KeylistFree(p->pList);
  3848   3848     p->pList = p->keylistStack[p->keylistStackDepth];

Changes to src/where.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This module contains C code that generates VDBE code used to process
    13     13   ** the WHERE clause of SQL statements.  Also found here are subroutines
    14     14   ** to generate VDBE code to evaluate expressions.
    15     15   **
    16         -** $Id: where.c,v 1.45 2002/05/21 13:18:26 drh Exp $
           16  +** $Id: where.c,v 1.46 2002/05/24 02:04:34 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   
    20     20   /*
    21     21   ** The query generator uses an array of instances of this structure to
    22     22   ** help it analyze the subexpressions of the WHERE clause.  Each WHERE
    23     23   ** clause subexpression is separated from the others by an AND operator.
................................................................................
   155    155   ** in order to complete the WHERE clause processing.
   156    156   **
   157    157   ** If an error occurs, this routine returns NULL.
   158    158   */
   159    159   WhereInfo *sqliteWhereBegin(
   160    160     Parse *pParse,       /* The parser context */
   161    161     int base,            /* VDBE cursor index for left-most table in pTabList */
   162         -  IdList *pTabList,    /* A list of all tables */
          162  +  SrcList *pTabList,   /* A list of all tables to be scanned */
   163    163     Expr *pWhere,        /* The WHERE clause */
   164    164     int pushKey          /* If TRUE, leave the table key on the stack */
   165    165   ){
   166    166     int i;                     /* Loop counter */
   167    167     WhereInfo *pWInfo;         /* Will become the return value of this function */
   168    168     Vdbe *v = pParse->pVdbe;   /* The virtual database engine */
   169    169     int brk, cont;             /* Addresses used during code generation */
................................................................................
   174    174     int aDirect[32];     /* If TRUE, then index this table using ROWID */
   175    175     int iDirectEq[32];   /* Term of the form ROWID==X for the N-th table */
   176    176     int iDirectLt[32];   /* Term of the form ROWID<X or ROWID<=X */
   177    177     int iDirectGt[32];   /* Term of the form ROWID>X or ROWID>=X */
   178    178     ExprInfo aExpr[50];  /* The WHERE clause is divided into these expressions */
   179    179   
   180    180     /* Allocate space for aOrder[] and aiMem[]. */
   181         -  aOrder = sqliteMalloc( sizeof(int) * pTabList->nId );
          181  +  aOrder = sqliteMalloc( sizeof(int) * pTabList->nSrc );
   182    182   
   183    183     /* Allocate and initialize the WhereInfo structure that will become the
   184    184     ** return value.
   185    185     */
   186         -  pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nId*sizeof(WhereLevel) );
          186  +  pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel));
   187    187     if( sqlite_malloc_failed ){
   188    188       sqliteFree(aOrder);
   189    189       sqliteFree(pWInfo);
   190    190       return 0;
   191    191     }
   192    192     pWInfo->pParse = pParse;
   193    193     pWInfo->pTabList = pTabList;
................................................................................
   235    235           aExpr[i].prereqAll &= mask;
   236    236         }
   237    237       }
   238    238     }
   239    239   
   240    240     /* Figure out a good nesting order for the tables.  aOrder[0] will
   241    241     ** be the index in pTabList of the outermost table.  aOrder[1] will
   242         -  ** be the first nested loop and so on.  aOrder[pTabList->nId-1] will
          242  +  ** be the first nested loop and so on.  aOrder[pTabList->nSrc-1] will
   243    243     ** be the innermost loop.
   244    244     **
   245    245     ** Someday we will put in a good algorithm here to reorder the loops
   246    246     ** for an effiecient query.  But for now, just use whatever order the
   247    247     ** tables appear in in the pTabList.
   248    248     */
   249         -  for(i=0; i<pTabList->nId; i++){
          249  +  for(i=0; i<pTabList->nSrc; i++){
   250    250       aOrder[i] = i;
   251    251     }
   252    252   
   253    253     /* Figure out what index to use (if any) for each nested loop.
   254    254     ** Make pWInfo->a[i].pIdx point to the index to use for the i-th nested
   255         -  ** loop where i==0 is the outer loop and i==pTabList->nId-1 is the inner
          255  +  ** loop where i==0 is the outer loop and i==pTabList->nSrc-1 is the inner
   256    256     ** loop. 
   257    257     **
   258    258     ** If terms exist that use the ROWID of any table, then set the
   259    259     ** iDirectEq[], iDirectLt[], or iDirectGt[] elements for that table
   260    260     ** to the index of the term containing the ROWID.  We always prefer
   261    261     ** to use a ROWID which can directly access a table rather than an
   262    262     ** index which requires reading an index first to get the rowid then
................................................................................
   263    263     ** doing a second read of the actual database table.
   264    264     **
   265    265     ** Actually, if there are more than 32 tables in the join, only the
   266    266     ** first 32 tables are candidates for indices.  This is (again) due
   267    267     ** to the limit of 32 bits in an integer bitmask.
   268    268     */
   269    269     loopMask = 0;
   270         -  for(i=0; i<pTabList->nId && i<ARRAYSIZE(aDirect); i++){
          270  +  for(i=0; i<pTabList->nSrc && i<ARRAYSIZE(aDirect); i++){
   271    271       int j;
   272    272       int idx = aOrder[i];
   273    273       Table *pTab = pTabList->a[idx].pTab;
   274    274       Index *pIdx;
   275    275       Index *pBestIdx = 0;
   276    276       int bestScore = 0;
   277    277   
................................................................................
   422    422         pWInfo->a[i].iCur = pParse->nTab++;
   423    423         pWInfo->peakNTab = pParse->nTab;
   424    424       }
   425    425     }
   426    426   
   427    427     /* Open all tables in the pTabList and all indices used by those tables.
   428    428     */
   429         -  for(i=0; i<pTabList->nId; i++){
          429  +  for(i=0; i<pTabList->nSrc; i++){
   430    430       int openOp;
   431    431       Table *pTab;
   432    432   
   433    433       pTab = pTabList->a[i].pTab;
   434    434       if( pTab->isTransient || pTab->pSelect ) continue;
   435    435       openOp = pTab->isTemp ? OP_OpenAux : OP_Open;
   436    436       sqliteVdbeAddOp(v, openOp, base+i, pTab->tnum);
................................................................................
   445    445         sqliteVdbeChangeP3(v, -1, pWInfo->a[i].pIdx->zName, P3_STATIC);
   446    446       }
   447    447     }
   448    448   
   449    449     /* Generate the code to do the search
   450    450     */
   451    451     loopMask = 0;
   452         -  for(i=0; i<pTabList->nId; i++){
          452  +  for(i=0; i<pTabList->nSrc; i++){
   453    453       int j, k;
   454    454       int idx = aOrder[i];
   455    455       Index *pIdx;
   456    456       WhereLevel *pLevel = &pWInfo->a[i];
   457    457   
   458    458       pIdx = pLevel->pIdx;
   459    459       if( i<ARRAYSIZE(iDirectEq) && iDirectEq[i]>=0 ){
................................................................................
   469    469         }else{
   470    470           sqliteExprCode(pParse, aExpr[k].p->pLeft);
   471    471         }
   472    472         aExpr[k].p = 0;
   473    473         brk = pLevel->brk = sqliteVdbeMakeLabel(v);
   474    474         cont = pLevel->cont = brk;
   475    475         sqliteVdbeAddOp(v, OP_MustBeInt, 0, brk);
   476         -      if( i==pTabList->nId-1 && pushKey ){
          476  +      if( i==pTabList->nSrc-1 && pushKey ){
   477    477           /* Note: The OP_Dup below will cause the recno to be left on the
   478    478           ** stack if the record does not exists and the OP_NotExists jump is
   479    479           ** taken.  This violates a general rule of the VDBE that you should
   480    480           ** never leave values on the stack in order to avoid a stack overflow.
   481    481           ** But in this case, the OP_Dup will never happen inside of a loop,
   482    482           ** because the pushKey flag is only true for UPDATE and DELETE, not
   483    483           ** for SELECT, and nested loops only occur on a SELECT.
................................................................................
   532    532           sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
   533    533           testOp = OP_IdxGE;
   534    534         }
   535    535         sqliteVdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk);
   536    536         start = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
   537    537         sqliteVdbeAddOp(v, testOp, pLevel->iCur, brk);
   538    538         sqliteVdbeAddOp(v, OP_IdxRecno, pLevel->iCur, 0);
   539         -      if( i==pTabList->nId-1 && pushKey ){
          539  +      if( i==pTabList->nSrc-1 && pushKey ){
   540    540           haveKey = 1;
   541    541         }else{
   542    542           sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0);
   543    543           haveKey = 0;
   544    544         }
   545    545         pLevel->op = OP_Next;
   546    546         pLevel->p1 = pLevel->iCur;
................................................................................
   755    755         */
   756    756         start = sqliteVdbeCurrentAddr(v);
   757    757         if( testOp!=OP_Noop ){
   758    758           sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
   759    759           sqliteVdbeAddOp(v, testOp, pLevel->iCur, brk);
   760    760         }
   761    761         sqliteVdbeAddOp(v, OP_IdxRecno, pLevel->iCur, 0);
   762         -      if( i==pTabList->nId-1 && pushKey ){
          762  +      if( i==pTabList->nSrc-1 && pushKey ){
   763    763           haveKey = 1;
   764    764         }else{
   765    765           sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0);
   766    766           haveKey = 0;
   767    767         }
   768    768   
   769    769         /* Record the instruction used to terminate the loop.
................................................................................
   801    801   ** Generate the end of the WHERE loop.
   802    802   */
   803    803   void sqliteWhereEnd(WhereInfo *pWInfo){
   804    804     Vdbe *v = pWInfo->pParse->pVdbe;
   805    805     int i;
   806    806     int base = pWInfo->base;
   807    807     WhereLevel *pLevel;
   808         -  IdList *pTabList = pWInfo->pTabList;
          808  +  SrcList *pTabList = pWInfo->pTabList;
   809    809   
   810         -  for(i=pTabList->nId-1; i>=0; i--){
          810  +  for(i=pTabList->nSrc-1; i>=0; i--){
   811    811       pLevel = &pWInfo->a[i];
   812    812       sqliteVdbeResolveLabel(v, pLevel->cont);
   813    813       if( pLevel->op!=OP_Noop ){
   814    814         sqliteVdbeAddOp(v, pLevel->op, pLevel->p1, pLevel->p2);
   815    815       }
   816    816       sqliteVdbeResolveLabel(v, pLevel->brk);
   817    817     }
   818    818     sqliteVdbeResolveLabel(v, pWInfo->iBreak);
   819         -  for(i=0; i<pTabList->nId; i++){
          819  +  for(i=0; i<pTabList->nSrc; i++){
   820    820       if( pTabList->a[i].pTab->isTransient ) continue;
   821    821       pLevel = &pWInfo->a[i];
   822    822       sqliteVdbeAddOp(v, OP_Close, base+i, 0);
   823    823       if( pLevel->pIdx!=0 ){
   824    824         sqliteVdbeAddOp(v, OP_Close, pLevel->iCur, 0);
   825    825       }
   826    826     }
   827    827     if( pWInfo->pParse->nTab==pWInfo->peakNTab ){
   828    828       pWInfo->pParse->nTab = pWInfo->savedNTab;
   829    829     }
   830    830     sqliteFree(pWInfo);
   831    831     return;
   832    832   }