diff options
author | drh <drh@noemail.net> | 2012-12-19 02:36:45 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2012-12-19 02:36:45 +0000 |
commit | 8f25d18b21c2f8076b02ced2b57ef3bc29b56427 (patch) | |
tree | d6a3c38f5145d3f413f0e99f1807bc0f6c078153 /src/resolve.c | |
parent | 832ee3d4ccf2941b17e718743ae7283f2e97a571 (diff) | |
download | sqlite-8f25d18b21c2f8076b02ced2b57ef3bc29b56427.tar.gz sqlite-8f25d18b21c2f8076b02ced2b57ef3bc29b56427.zip |
Better resolution of table and column names in joins where some of the
terms of the FROM clause are parenthesized.
FossilOrigin-Name: 7344e791b9456286ecdca6d45f2f5260fb3f10e2
Diffstat (limited to 'src/resolve.c')
-rw-r--r-- | src/resolve.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/src/resolve.c b/src/resolve.c index eb594d159..317ca3d81 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -206,6 +206,20 @@ static int lookupName( pExpr->pTab = 0; ExprSetIrreducible(pExpr); + /* Translate the schema name in zDb into a pointer to the corresponding + ** schema. If not found, pSchema will remain NULL and nothing will match + ** resulting in an appropriate error message toward the end of this routine + */ + if( zDb ){ + for(i=0; i<db->nDb; i++){ + assert( db->aDb[i].zName ); + if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){ + pSchema = db->aDb[i].pSchema; + break; + } + } + } + /* Start at the inner-most context and move outward until a match is found */ while( pNC && cnt==0 ){ ExprList *pEList; @@ -214,31 +228,36 @@ static int lookupName( if( pSrcList ){ for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){ Table *pTab; - int iDb; Column *pCol; pTab = pItem->pTab; assert( pTab!=0 && pTab->zName!=0 ); - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( pTab->nCol>0 ); - if( zTab ){ - if( pItem->zAlias ){ - char *zTabName = pItem->zAlias; - if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue; - }else{ - char *zTabName = pTab->zName; - if( NEVER(zTabName==0) || sqlite3StrICmp(zTabName, zTab)!=0 ){ - continue; - } - if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){ - continue; + if( zDb && pTab->pSchema!=pSchema ){ + continue; + } + if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){ + ExprList *pEList = pItem->pSelect->pEList; + int hit = 0; + for(j=0; j<pEList->nExpr; j++){ + if( zTab && sqlite3StrICmp(pEList->a[j].zSpan, zTab)!=0 ) continue; + if( sqlite3StrICmp(pEList->a[j].zName, zCol)==0 ){ + cnt++; + cntTab = 2; + pMatch = pItem; + pExpr->iColumn = j; } } + if( hit || zTab==0 ) continue; + } + if( zTab ){ + const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName; + assert( zTabName!=0 ); + if( sqlite3StrICmp(zTabName, zTab)!=0 ){ + continue; + } } if( 0==(cntTab++) ){ - pExpr->iTable = pItem->iCursor; - pExpr->pTab = pTab; - pSchema = pTab->pSchema; pMatch = pItem; } for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){ @@ -252,17 +271,19 @@ static int lookupName( if( nameInUsingClause(pItem->pUsing, zCol) ) continue; } cnt++; - pExpr->iTable = pItem->iCursor; - pExpr->pTab = pTab; pMatch = pItem; - pSchema = pTab->pSchema; /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j; break; } } } - } + if( pMatch ){ + pExpr->iTable = pMatch->iCursor; + pExpr->pTab = pMatch->pTab; + pSchema = pExpr->pTab->pSchema; + } + } /* if( pSrcList ) */ #ifndef SQLITE_OMIT_TRIGGER /* If we have not already resolved the name, then maybe |