diff options
author | drh <drh@noemail.net> | 2011-10-18 18:10:40 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2011-10-18 18:10:40 +0000 |
commit | e802c5da0101e9a3b4ad5e8925f47e636f8a9f3b (patch) | |
tree | 7487c7ca193431d5f39c622a3d571d13b6212318 /src/resolve.c | |
parent | 42495cd46fb4c41b29306e5f61ae259ab3758225 (diff) | |
download | sqlite-e802c5da0101e9a3b4ad5e8925f47e636f8a9f3b.tar.gz sqlite-e802c5da0101e9a3b4ad5e8925f47e636f8a9f3b.zip |
Improved handling of USING and NATURAL JOIN in 3-way and higher joins.
Ticket [3338b3fa19ac4ab]
FossilOrigin-Name: 551ce407bd77149865423511bd52eba2f404161a
Diffstat (limited to 'src/resolve.c')
-rw-r--r-- | src/resolve.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/src/resolve.c b/src/resolve.c index d29d2a834..6d857f007 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -98,6 +98,24 @@ static void resolveAlias( sqlite3DbFree(db, pDup); } + +/* +** Return TRUE if the name zCol occurs anywhere in the USING clause. +** +** Return FALSE if the USING clause is NULL or if it does not contain +** zCol. +*/ +static int nameInUsingClause(IdList *pUsing, const char *zCol){ + if( pUsing ){ + int k; + for(k=0; k<pUsing->nId; k++){ + if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1; + } + } + return 0; +} + + /* ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up ** that name in the set of source tables in pSrcList and make the pExpr @@ -189,7 +207,14 @@ static int lookupName( } for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){ if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ - IdList *pUsing; + /* If there has been exactly one prior match and this match + ** is for the right-hand table of a NATURAL JOIN or is in a + ** USING clause, then skip this match. + */ + if( cnt==1 ){ + if( pItem->jointype & JT_NATURAL ) continue; + if( nameInUsingClause(pItem->pUsing, zCol) ) continue; + } cnt++; pExpr->iTable = pItem->iCursor; pExpr->pTab = pTab; @@ -197,26 +222,6 @@ static int lookupName( pSchema = pTab->pSchema; /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j; - if( i<pSrcList->nSrc-1 ){ - if( pItem[1].jointype & JT_NATURAL ){ - /* If this match occurred in the left table of a natural join, - ** then skip the right table to avoid a duplicate match */ - pItem++; - i++; - }else if( (pUsing = pItem[1].pUsing)!=0 ){ - /* If this match occurs on a column that is in the USING clause - ** of a join, skip the search of the right table of the join - ** to avoid a duplicate match there. */ - int k; - for(k=0; k<pUsing->nId; k++){ - if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){ - pItem++; - i++; - break; - } - } - } - } break; } } |