-C Improve\stest\scoverage\sof\sfts3.c.
-D 2009-12-09T14:39:41
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+C The\sUSING\sclause\sand\sNATURAL\sJOIN\slook\sat\sall\stables\sto\sthe\sleft\swhen\nsearching\sfor\sa\smatch,\snot\sjust\sthe\sone\stable\sto\sthe\simmediate\sleft.\nTables\sfurther\sto\sthe\sleft\sare\spreferred.\nFix\sfor\sticket\s[f74beaabde].\s\sStill\sneed\sto\sadd\stest\scases\sto\scomplete\nthe\sticket.
+D 2009-12-09T17:36:40
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in c5827ead754ab32b9585487177c93bb00b9497b3
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c d052e5c44bab34f83b3c1741aaa07478d18b5dd5
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
-F src/select.c 2f9ed7482e7a25b0b127fc41693bbdbe1caf5647
+F src/select.c 68c58dc49341472e4e5661a47a1a9e5f8a161340
F src/shell.c f4948cb6d30665d755a6b5e0ec313d1094aab828
F src/sqlite.h.in 338e1ac00faa7e3a536e7f1120827dd1f6432981
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P a9038306c33c88120d8bef27209d8f0641c85c9b
-R db340fa6c4afcd8bc8679373cdbca6c1
-U dan
-Z eeb82c42887166b9ef7e8ca6456b81ff
+P 56b6432f8622d53ffd3a4d9a2244114f8531ed71
+R c60687f3ab920ee77b412f18848340fb
+U drh
+Z 12648e9ade5661889385face890b1540
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.6 (GNU/Linux)
+
+iD8DBQFLH+AsoxKgR168RlERAqq+AJ42LhMfpcSfI/s5lEGDLv5D00O41wCfWMQf
+iT/qNX5HigqUQ+DEbiPla9M=
+=Wtyb
+-----END PGP SIGNATURE-----
return -1;
}
+/*
+** Search the first N tables in pSrc, from left to right, looking for a
+** table that has a column named zCol.
+**
+** When found, set *piTab and *piCol to the table index and column index
+** of the matching column and return TRUE.
+**
+** If not found, return FALSE.
+*/
+static int tableAndColumnIndex(
+ SrcList *pSrc, /* Array of tables to search */
+ int N, /* Number of tables in pSrc->a[] to search */
+ const char *zCol, /* Name of the column we are looking for */
+ int *piTab, /* Write index of pSrc->a[] here */
+ int *piCol /* Write index of pSrc->a[*piTab].pTab->aCol[] here */
+){
+ int i; /* For looping over tables in pSrc */
+ int iCol; /* Index of column matching zCol */
+
+ assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */
+ for(i=0; i<N; i++){
+ iCol = columnIndex(pSrc->a[i].pTab, zCol);
+ if( iCol>=0 ){
+ if( piTab ){
+ *piTab = i;
+ *piCol = iCol;
+ }
+ return 1;
+ }
+ }
+ return 0;
+}
+
/*
** This function is used to add terms implied by JOIN syntax to the
** WHERE clause expression of a SELECT statement. The new term, which
static void addWhereTerm(
Parse *pParse, /* Parsing context */
SrcList *pSrc, /* List of tables in FROM clause */
- int iSrc, /* Index of first table to join in pSrc */
+ int iLeft, /* Index of first table to join in pSrc */
int iColLeft, /* Index of column in first table */
+ int iRight, /* Index of second table in pSrc */
int iColRight, /* Index of column in second table */
int isOuterJoin, /* True if this is an OUTER join */
Expr **ppWhere /* IN/OUT: The WHERE clause to add to */
Expr *pE2;
Expr *pEq;
- assert( pSrc->nSrc>(iSrc+1) );
- assert( pSrc->a[iSrc].pTab );
- assert( pSrc->a[iSrc+1].pTab );
+ assert( iLeft<iRight );
+ assert( pSrc->nSrc>iRight );
+ assert( pSrc->a[iLeft].pTab );
+ assert( pSrc->a[iRight].pTab );
- pE1 = sqlite3CreateColumnExpr(db, pSrc, iSrc, iColLeft);
- pE2 = sqlite3CreateColumnExpr(db, pSrc, iSrc+1, iColRight);
+ pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft);
+ pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight);
pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2, 0);
if( pEq && isOuterJoin ){
"an ON or USING clause", 0);
return 1;
}
- for(j=0; j<pLeftTab->nCol; j++){
- char *zName = pLeftTab->aCol[j].zName;
- int iRightCol = columnIndex(pRightTab, zName);
- if( iRightCol>=0 ){
- addWhereTerm(pParse, pSrc, i, j, iRightCol, isOuter, &p->pWhere);
+ for(j=0; j<pRightTab->nCol; j++){
+ char *zName; /* Name of column in the right table */
+ int iLeft; /* Matching left table */
+ int iLeftCol; /* Matching column in the left table */
+
+ zName = pRightTab->aCol[j].zName;
+ if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol) ){
+ addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j,
+ isOuter, &p->pWhere);
}
}
}
if( pRight->pUsing ){
IdList *pList = pRight->pUsing;
for(j=0; j<pList->nId; j++){
- char *zName = pList->a[j].zName;
- int iLeftCol = columnIndex(pLeftTab, zName);
- int iRightCol = columnIndex(pRightTab, zName);
- if( iLeftCol<0 || iRightCol<0 ){
+ char *zName; /* Name of the term in the USING clause */
+ int iLeft; /* Table on the left with matching column name */
+ int iLeftCol; /* Column number of matching column on the left */
+ int iRightCol; /* Column number of matching column on the right */
+
+ zName = pList->a[j].zName;
+ iRightCol = columnIndex(pRightTab, zName);
+ if( iRightCol<0
+ || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol)
+ ){
sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
"not present in both tables", zName);
return 1;
}
- addWhereTerm(pParse, pSrc, i, iLeftCol, iRightCol, isOuter, &p->pWhere);
+ addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol,
+ isOuter, &p->pWhere);
}
}
}
}
if( i>0 && zTName==0 ){
- struct SrcList_item *pLeft = &pTabList->a[i-1];
- if( (pLeft[1].jointype & JT_NATURAL)!=0 &&
- columnIndex(pLeft->pTab, zName)>=0 ){
+ if( (pFrom->jointype & JT_NATURAL)!=0
+ && tableAndColumnIndex(pTabList, i, zName, 0, 0)
+ ){
/* In a NATURAL join, omit the join columns from the
- ** table on the right */
+ ** table to the right of the join */
continue;
}
- if( sqlite3IdListIndex(pLeft[1].pUsing, zName)>=0 ){
+ if( sqlite3IdListIndex(pFrom->pUsing, zName)>=0 ){
/* In a join with a USING clause, omit columns in the
** using clause from the table on the right. */
continue;