diff options
author | drh <> | 2022-04-21 13:11:26 +0000 |
---|---|---|
committer | drh <> | 2022-04-21 13:11:26 +0000 |
commit | 18f8600fe6fa709cc2ceaa78982e433737432784 (patch) | |
tree | 1885b3428321ad86b83c73841b3de4b32e9b6252 /src/resolve.c | |
parent | 22b410d894fa44d7944c4f0ca5448d3937123f64 (diff) | |
download | sqlite-18f8600fe6fa709cc2ceaa78982e433737432784.tar.gz sqlite-18f8600fe6fa709cc2ceaa78982e433737432784.zip |
Avoid materializing columns of SF_NestedFrom subqueries that are never used.
Other code improvements manually imported from the right-join-paren branch.
FossilOrigin-Name: cd8272fc2a34d1b245fd95208b9b601266ee7d2ff0f5ce52d03752f2c4e852a2
Diffstat (limited to 'src/resolve.c')
-rw-r--r-- | src/resolve.c | 77 |
1 files changed, 42 insertions, 35 deletions
diff --git a/src/resolve.c b/src/resolve.c index 446004bfe..e9cfe9d9f 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -265,6 +265,7 @@ static int lookupName( assert( pNC ); /* the name context cannot be NULL. */ assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ + assert( zDb==0 || zTab!=0 ); assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); /* Initialize the node to no-match */ @@ -327,47 +328,50 @@ static int lookupName( assert( pEList!=0 ); assert( pEList->nExpr==pTab->nCol ); for(j=0; j<pEList->nExpr; j++){ - if( sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){ - if( cnt>0 ){ - if( pItem->fg.isUsing==0 - || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 - ){ - /* Two or more tables have the same column name which is - ** not joined by USING. This is an error. Signal as much - ** by clearing pFJMatch and letting cnt go above 1. */ - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - }else - if( (pItem->fg.jointype & JT_RIGHT)==0 ){ - /* An INNER or LEFT JOIN. Use the left-most table */ - continue; - }else - if( (pItem->fg.jointype & JT_LEFT)==0 ){ - /* A RIGHT JOIN. Use the right-most table */ - cnt = 0; - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - }else{ - /* For a FULL JOIN, we must construct a coalesce() func */ - extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); - } + if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){ + continue; + } + if( cnt>0 ){ + if( pItem->fg.isUsing==0 + || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 + ){ + /* Two or more tables have the same column name which is + ** not joined by USING. This is an error. Signal as much + ** by clearing pFJMatch and letting cnt go above 1. */ + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else + if( (pItem->fg.jointype & JT_RIGHT)==0 ){ + /* An INNER or LEFT JOIN. Use the left-most table */ + continue; + }else + if( (pItem->fg.jointype & JT_LEFT)==0 ){ + /* A RIGHT JOIN. Use the right-most table */ + cnt = 0; + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else{ + /* For a FULL JOIN, we must construct a coalesce() func */ + extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); } - cnt++; - cntTab = 2; - pMatch = pItem; - pExpr->iColumn = j; - hit = 1; - pEList->a[j].bUsed = 1; } + cnt++; + cntTab = 2; + pMatch = pItem; + pExpr->iColumn = j; + pEList->a[j].bUsed = 1; + hit = 1; } if( hit || zTab==0 ) continue; } - if( zDb ){ - if( pTab->pSchema!=pSchema ) continue; - if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue; - } + assert( zDb==0 || zTab!=0 ); if( zTab ){ - const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName; + const char *zTabName; + if( zDb ){ + if( pTab->pSchema!=pSchema ) continue; + if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue; + } + zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName; assert( zTabName!=0 ); if( sqlite3StrICmp(zTabName, zTab)!=0 ){ continue; @@ -410,6 +414,9 @@ static int lookupName( pMatch = pItem; /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j; + if( pItem->fg.isNestedFrom ){ + sqlite3SrcItemColumnUsed(pItem, j); + } break; } } |