Changes to the "sqlite" structure that allow simultaneous operations on
multiple database files.  Many regession tests pass - but not all of them.
Do not use this version except for debugging SQLite itself. (CVS 883)

FossilOrigin-Name: d2fb2bb50cf1e13feb90995079f291384abd6ba9
diff --git a/src/expr.c b/src/expr.c
index 47a7dd1..576ae2d 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.89 2003/03/20 01:16:59 drh Exp $
+** $Id: expr.c,v 1.90 2003/03/27 12:51:25 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -493,16 +493,29 @@
       break; 
     }
   
-    /* A table name and column name:  ID.ID */
+    /* A table name and column name:     ID.ID
+    ** Or a database, table and column:  ID.ID.ID
+    */
     case TK_DOT: {
       int cnt = 0;             /* Number of matches */
       int cntTab = 0;          /* Number of matching tables */
       int i;                   /* Loop counter */
       Expr *pLeft, *pRight;    /* Left and right subbranches of the expr */
       char *zLeft, *zRight;    /* Text of an identifier */
+      char *zDb;               /* Name of database holding table */
+      sqlite *db = pParse->db;
 
-      pLeft = pExpr->pLeft;
       pRight = pExpr->pRight;
+      if( pRight->op==TK_ID ){
+        pLeft = pExpr->pLeft;
+        zDb = 0;
+      }else{
+        Expr *pDb = pExpr->pLeft;
+        assert( pDb && pDb->op==TK_ID && pDb->token.z );
+        zDb = sqliteStrNDup(pDb->token.z, pDb->token.n);
+        pLeft = pRight->pLeft;
+        pRight = pRight->pRight;
+      }
       assert( pLeft && pLeft->op==TK_ID && pLeft->token.z );
       assert( pRight && pRight->op==TK_ID && pRight->token.z );
       zLeft = sqliteStrNDup(pLeft->token.z, pLeft->token.n);
@@ -510,8 +523,10 @@
       if( zLeft==0 || zRight==0 ){
         sqliteFree(zLeft);
         sqliteFree(zRight);
+        sqliteFree(zDb);
         return 1;
       }
+      sqliteDequote(zDb);
       sqliteDequote(zLeft);
       sqliteDequote(zRight);
       pExpr->iTable = -1;
@@ -523,10 +538,14 @@
         assert( pTab->nCol>0 );
         if( pTabList->a[i].zAlias ){
           zTab = pTabList->a[i].zAlias;
+          if( sqliteStrICmp(zTab, zLeft)!=0 ) continue;
         }else{
           zTab = pTab->zName;
+          if( zTab==0 || sqliteStrICmp(zTab, zLeft)!=0 ) continue;
+          if( zDb!=0 && sqliteStrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){
+            continue;
+          }
         }
-        if( zTab==0 || sqliteStrICmp(zTab, zLeft)!=0 ) continue;
         if( 0==(cntTab++) ) pExpr->iTable = i + base;
         for(j=0; j<pTab->nCol; j++){
           if( sqliteStrICmp(pTab->aCol[j].zName, zRight)==0 ){
@@ -577,6 +596,7 @@
         pExpr->iColumn = -1;
         pExpr->dataType = SQLITE_SO_NUM;
       }
+      sqliteFree(zDb);
       sqliteFree(zLeft);
       sqliteFree(zRight);
       if( cnt==0 ){
@@ -592,9 +612,9 @@
         pParse->nErr++;
         return 1;
       }
-      sqliteExprDelete(pLeft);
+      sqliteExprDelete(pExpr->pLeft);
       pExpr->pLeft = 0;
-      sqliteExprDelete(pRight);
+      sqliteExprDelete(pExpr->pRight);
       pExpr->pRight = 0;
       pExpr->op = TK_COLUMN;
       sqliteAuthRead(pParse, pExpr, pTabList, base);