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)

FossilOrigin-Name: a167b71d8c27e870bc3079c6132e483bffc83298
diff --git a/src/expr.c b/src/expr.c
index 54b7334..94aa06d 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -12,7 +12,7 @@
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.62 2002/05/23 02:09:04 drh Exp $
+** $Id: expr.c,v 1.63 2002/05/24 02:04:33 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -155,11 +155,11 @@
 ** string space that is allocated separately from the expression tree
 ** itself.  These routines do NOT duplicate that string space.
 **
-** The expression list and ID list return by sqliteExprListDup() and 
-** sqliteIdListDup() can not be further expanded by subsequent calls
-** to sqliteExprListAppend() or sqliteIdListAppend().
+** The expression list, ID, and source lists return by sqliteExprListDup(),
+** sqliteIdListDup(), and sqliteSrcListDup() can not be further expanded 
+** by subsequent calls to sqlite*ListAppend() routines.
 **
-** Any tables that the ID list might point to are not duplicated.
+** Any tables that the SrcList might point to are not duplicated.
 */
 Expr *sqliteExprDup(Expr *p){
   Expr *pNew;
@@ -196,6 +196,26 @@
   }
   return pNew;
 }
+SrcList *sqliteSrcListDup(SrcList *p){
+  SrcList *pNew;
+  int i;
+  if( p==0 ) return 0;
+  pNew = sqliteMalloc( sizeof(*pNew) );
+  if( pNew==0 ) return 0;
+  pNew->nSrc = p->nSrc;
+  pNew->a = sqliteMalloc( p->nSrc*sizeof(p->a[0]) );
+  if( pNew->a==0 ) return 0;
+  for(i=0; i<p->nSrc; i++){
+    pNew->a[i].zName = sqliteStrDup(p->a[i].zName);
+    pNew->a[i].zAlias = sqliteStrDup(p->a[i].zAlias);
+    pNew->a[i].jointype = p->a[i].jointype;
+    pNew->a[i].pTab = 0;
+    pNew->a[i].pSelect = sqliteSelectDup(p->a[i].pSelect);
+    pNew->a[i].pOn = sqliteExprDup(p->a[i].pOn);
+    pNew->a[i].pUsing = sqliteIdListDup(p->a[i].pUsing);
+  }
+  return pNew;
+}
 IdList *sqliteIdListDup(IdList *p){
   IdList *pNew;
   int i;
@@ -207,10 +227,7 @@
   if( pNew->a==0 ) return 0;
   for(i=0; i<p->nId; i++){
     pNew->a[i].zName = sqliteStrDup(p->a[i].zName);
-    pNew->a[i].zAlias = sqliteStrDup(p->a[i].zAlias);
     pNew->a[i].idx = p->a[i].idx;
-    pNew->a[i].pTab = 0;
-    pNew->a[i].pSelect = sqliteSelectDup(p->a[i].pSelect);
   }
   return pNew;
 }
@@ -221,7 +238,7 @@
   if( pNew==0 ) return 0;
   pNew->isDistinct = p->isDistinct;
   pNew->pEList = sqliteExprListDup(p->pEList);
-  pNew->pSrc = sqliteIdListDup(p->pSrc);
+  pNew->pSrc = sqliteSrcListDup(p->pSrc);
   pNew->pWhere = sqliteExprDup(p->pWhere);
   pNew->pGroupBy = sqliteExprListDup(p->pGroupBy);
   pNew->pHaving = sqliteExprDup(p->pHaving);
@@ -362,12 +379,12 @@
 int sqliteExprResolveIds(
   Parse *pParse,     /* The parser context */
   int base,          /* VDBE cursor number for first entry in pTabList */
-  IdList *pTabList,  /* List of tables used to resolve column names */
+  SrcList *pTabList, /* List of tables used to resolve column names */
   ExprList *pEList,  /* List of expressions used to resolve "AS" */
   Expr *pExpr        /* The expression to be analyzed. */
 ){
   if( pExpr==0 || pTabList==0 ) return 0;
-  assert( base+pTabList->nId<=pParse->nTab );
+  assert( base+pTabList->nSrc<=pParse->nTab );
   switch( pExpr->op ){
     /* Double-quoted strings (ex: "abc") are used as identifiers if
     ** possible.  Otherwise they remain as strings.  Single-quoted
@@ -395,7 +412,7 @@
       z = sqliteStrNDup(pExpr->token.z, pExpr->token.n);
       sqliteDequote(z);
       if( z==0 ) return 1;
-      for(i=0; i<pTabList->nId; i++){
+      for(i=0; i<pTabList->nSrc; i++){
         int j;
         Table *pTab = pTabList->a[i].pTab;
         if( pTab==0 ) continue;
@@ -430,7 +447,7 @@
       if( cnt==0 && sqliteIsRowid(z) ){
         pExpr->iColumn = -1;
         pExpr->iTable = base;
-        cnt = 1 + (pTabList->nId>1);
+        cnt = 1 + (pTabList->nSrc>1);
         pExpr->op = TK_COLUMN;
       }
       sqliteFree(z);
@@ -470,7 +487,7 @@
       sqliteDequote(zLeft);
       sqliteDequote(zRight);
       pExpr->iTable = -1;
-      for(i=0; i<pTabList->nId; i++){
+      for(i=0; i<pTabList->nSrc; i++){
         int j;
         char *zTab;
         Table *pTab = pTabList->a[i].pTab;