diff options
author | dan <Dan Kennedy> | 2023-09-15 18:36:51 +0000 |
---|---|---|
committer | dan <Dan Kennedy> | 2023-09-15 18:36:51 +0000 |
commit | 81b70d97eb3ccf25d8fec5544009e6ebe9225b4a (patch) | |
tree | fce9a903cbc8d9ac0d341dd697e20af9f7931da3 /src/resolve.c | |
parent | 581b22936297aa4cc19f2ee1920804ce96d5459d (diff) | |
download | sqlite-81b70d97eb3ccf25d8fec5544009e6ebe9225b4a.tar.gz sqlite-81b70d97eb3ccf25d8fec5544009e6ebe9225b4a.zip |
Allow expressions like "<tbl>.rowid" to refer to implicit rowid columns of tables in nested FROM clauses.
FossilOrigin-Name: 59a1bbc69f5dbb33418fa4b383393fb13a46bc1e531577da8ad54ae2fad5a10e
Diffstat (limited to 'src/resolve.c')
-rw-r--r-- | src/resolve.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/src/resolve.c b/src/resolve.c index 7fc0151ad..20bce29a2 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -104,21 +104,35 @@ static void resolveAlias( } /* -** Subqueries stores the original database, table and column names for their -** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN". -** Check to see if the zSpan given to this routine matches the zDb, zTab, -** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will -** match anything. +** Subqueries store the original database, table and column names for their +** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN", +** and mark the expression-list item by setting ExprList.a[].fg.eEName +** to ENAME_TAB. +** +** Check to see if the zSpan/eEName of the expression-list item passed to this +** routine matches the zDb, zTab, and zCol. If any of zDb, zTab, and zCol are +** NULL then those fields will match anything. Return true if there is a match, +** or false otherwise. +** +** SF_NestedFrom subqueries also store an entry for the implicit rowid (or +** _rowid_, or oid) column by setting ExprList.a[].fg.eEName to ENAME_ROWID, +** and setting zSpan to "DATABASE.TABLE.<rowid-alias>". This type of pItem +** argument matches if bRowidOk is true, zTab is not NULL, zCol is a rowid +** alias, and zDb matches as for the usual case. */ int sqlite3MatchEName( const struct ExprList_item *pItem, const char *zCol, const char *zTab, - const char *zDb + const char *zDb, + int bRowidOk ){ int n; const char *zSpan; - if( pItem->fg.eEName!=ENAME_TAB ) return 0; + int eEName = pItem->fg.eEName; + if( eEName!=ENAME_TAB && (eEName!=ENAME_ROWID || bRowidOk==0 || zTab==0) ){ + return 0; + } zSpan = pItem->zEName; for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){ @@ -130,8 +144,9 @@ int sqlite3MatchEName( return 0; } zSpan += n+1; - if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){ - return 0; + if( zCol ){ + if( eEName==ENAME_TAB && sqlite3StrICmp(zSpan, zCol)!=0 ) return 0; + if( eEName==ENAME_ROWID && sqlite3IsRowid(zCol)==0 ) return 0; } return 1; } @@ -342,7 +357,7 @@ 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( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb, cnt==0) ){ continue; } if( cnt>0 ){ |