mirror of
https://github.com/sqlite/sqlite.git
synced 2025-12-13 22:42:20 +03:00
Fix resolution of unqualified "rowid" identifiers in queries with nested joins.
FossilOrigin-Name: bbcbd3d537d6790373d97f59386b8ce7fa2177db572af0f1babe058a76e25cc3
This commit is contained in:
19
manifest
19
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Allow\sexpressions\slike\s"<tbl>.rowid"\sto\srefer\sto\simplicit\srowid\scolumns\sof\stables\sin\snested\sFROM\sclauses.
|
C Fix\sresolution\sof\sunqualified\s"rowid"\sidentifiers\sin\squeries\swith\snested\sjoins.
|
||||||
D 2023-09-15T18:36:51.501
|
D 2023-09-15T20:57:05.776
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@@ -708,14 +708,14 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
|
|||||||
F src/prepare.c 80548297dc0e1fb3139cdebffb5a1bcac3dfac66d791012dd74838e70445072d
|
F src/prepare.c 80548297dc0e1fb3139cdebffb5a1bcac3dfac66d791012dd74838e70445072d
|
||||||
F src/printf.c e3ba080e2f409f9bfcc8d34724e6fc160e9c718dc92d0548f6b71b8b6f860ce2
|
F src/printf.c e3ba080e2f409f9bfcc8d34724e6fc160e9c718dc92d0548f6b71b8b6f860ce2
|
||||||
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||||
F src/resolve.c f31aab54a4bcb1a3e592daa6b657b7d3a725e40bf764a652dc175006ed4eead2
|
F src/resolve.c 1cbb3dacd41882dabe07209242d015f100d36cfb685235278b1d4e15711017b7
|
||||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||||
F src/select.c 5e9ff0eb38e5341780a70e3a39ea1d447c237552d1f552416dc605c123bf2acd
|
F src/select.c 5e9ff0eb38e5341780a70e3a39ea1d447c237552d1f552416dc605c123bf2acd
|
||||||
F src/shell.c.in 62708bea44d4e43aa7b1270ed422d1d29e82297924d4e0f223c39336a3f582f8
|
F src/shell.c.in 62708bea44d4e43aa7b1270ed422d1d29e82297924d4e0f223c39336a3f582f8
|
||||||
F src/sqlite.h.in 931a58d119d5cf87110648f39fa0bb9f1738b0068cb68250d893304a471bd6c0
|
F src/sqlite.h.in 931a58d119d5cf87110648f39fa0bb9f1738b0068cb68250d893304a471bd6c0
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h 2f30b2671f4c03cd27a43f039e11251391066c97d11385f5f963bb40b03038ac
|
F src/sqlite3ext.h 2f30b2671f4c03cd27a43f039e11251391066c97d11385f5f963bb40b03038ac
|
||||||
F src/sqliteInt.h 6cac7a6d674ea44fa867d929786ddec86df9be64c24d59afbf15c7bac671067c
|
F src/sqliteInt.h f2d713fac835f32b131d8a334595b0c471ede3796dab527c705d2b03c32d14e9
|
||||||
F src/sqliteLimit.h 33b1c9baba578d34efe7dfdb43193b366111cdf41476b1e82699e14c11ee1fb6
|
F src/sqliteLimit.h 33b1c9baba578d34efe7dfdb43193b366111cdf41476b1e82699e14c11ee1fb6
|
||||||
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
|
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
|
||||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||||
@@ -1290,7 +1290,7 @@ F test/joinC.test 1f1a602c2127f55f136e2cbd3bf2d26546614bf8cffe5902ec1ac9c07f87f2
|
|||||||
F test/joinD.test 2ce62e7353a0702ca5e70008faf319c1d4686aa19fba34275c6d1da0e960be28
|
F test/joinD.test 2ce62e7353a0702ca5e70008faf319c1d4686aa19fba34275c6d1da0e960be28
|
||||||
F test/joinE.test d5d182f3812771e2c0d97c9dcf5dbe4c41c8e21c82560e59358731c4a3981d6b
|
F test/joinE.test d5d182f3812771e2c0d97c9dcf5dbe4c41c8e21c82560e59358731c4a3981d6b
|
||||||
F test/joinF.test 53dd66158806823ea680dd7543b5406af151b5aafa5cd06a7f3231cd94938127
|
F test/joinF.test 53dd66158806823ea680dd7543b5406af151b5aafa5cd06a7f3231cd94938127
|
||||||
F test/joinH.test 44c51631e487a55902b2ed05706cad19c3ecdd86b7e1c7c8aa84457cec564d11
|
F test/joinH.test 832a33079ee8fba7e33fa5ac77c481b3fd8399ba16362d4524a0be22a060b9f2
|
||||||
F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497
|
F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497
|
||||||
F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
|
F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
|
||||||
F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e
|
F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e
|
||||||
@@ -2121,11 +2121,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P ce339046416e9ddeffe77f71a8bfb8c5b302160c3207f919aebd62902618ed59
|
P 59a1bbc69f5dbb33418fa4b383393fb13a46bc1e531577da8ad54ae2fad5a10e
|
||||||
R bcfd521e8d34de98592bf4e489ebb783
|
R 790b7202228cf2f5b7a7a80533c697dd
|
||||||
T *branch * nested-from-rowid-expansion
|
|
||||||
T *sym-nested-from-rowid-expansion *
|
|
||||||
T -sym-trunk *
|
|
||||||
U dan
|
U dan
|
||||||
Z dee6d86baf948e05aa8b2bb5ee3449dc
|
Z ce4b0349e1c5a42e7e7210175df9fc25
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
59a1bbc69f5dbb33418fa4b383393fb13a46bc1e531577da8ad54ae2fad5a10e
|
bbcbd3d537d6790373d97f59386b8ce7fa2177db572af0f1babe058a76e25cc3
|
||||||
@@ -117,22 +117,23 @@ static void resolveAlias(
|
|||||||
** SF_NestedFrom subqueries also store an entry for the implicit rowid (or
|
** 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,
|
** _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
|
** 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
|
** argument matches if zCol is a rowid alias. If it is not NULL, (*pbRowid)
|
||||||
** alias, and zDb matches as for the usual case.
|
** is set to 1 if there is this kind of match.
|
||||||
*/
|
*/
|
||||||
int sqlite3MatchEName(
|
int sqlite3MatchEName(
|
||||||
const struct ExprList_item *pItem,
|
const struct ExprList_item *pItem,
|
||||||
const char *zCol,
|
const char *zCol,
|
||||||
const char *zTab,
|
const char *zTab,
|
||||||
const char *zDb,
|
const char *zDb,
|
||||||
int bRowidOk
|
int *pbRowid
|
||||||
){
|
){
|
||||||
int n;
|
int n;
|
||||||
const char *zSpan;
|
const char *zSpan;
|
||||||
int eEName = pItem->fg.eEName;
|
int eEName = pItem->fg.eEName;
|
||||||
if( eEName!=ENAME_TAB && (eEName!=ENAME_ROWID || bRowidOk==0 || zTab==0) ){
|
if( eEName!=ENAME_TAB && (eEName!=ENAME_ROWID || pbRowid==0) ){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
assert( pbRowid==0 || *pbRowid==0 );
|
||||||
zSpan = pItem->zEName;
|
zSpan = pItem->zEName;
|
||||||
for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
|
for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
|
||||||
if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){
|
if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){
|
||||||
@@ -148,6 +149,7 @@ int sqlite3MatchEName(
|
|||||||
if( eEName==ENAME_TAB && sqlite3StrICmp(zSpan, zCol)!=0 ) return 0;
|
if( eEName==ENAME_TAB && sqlite3StrICmp(zSpan, zCol)!=0 ) return 0;
|
||||||
if( eEName==ENAME_ROWID && sqlite3IsRowid(zCol)==0 ) return 0;
|
if( eEName==ENAME_ROWID && sqlite3IsRowid(zCol)==0 ) return 0;
|
||||||
}
|
}
|
||||||
|
if( eEName==ENAME_ROWID ) *pbRowid = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,9 +359,11 @@ static int lookupName(
|
|||||||
assert( pEList!=0 );
|
assert( pEList!=0 );
|
||||||
assert( pEList->nExpr==pTab->nCol );
|
assert( pEList->nExpr==pTab->nCol );
|
||||||
for(j=0; j<pEList->nExpr; j++){
|
for(j=0; j<pEList->nExpr; j++){
|
||||||
if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb, cnt==0) ){
|
int bRowid = 0; /* True if possible rowid match */
|
||||||
|
if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb, &bRowid) ){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if( bRowid==0 ){
|
||||||
if( cnt>0 ){
|
if( cnt>0 ){
|
||||||
if( pItem->fg.isUsing==0
|
if( pItem->fg.isUsing==0
|
||||||
|| sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0
|
|| sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0
|
||||||
@@ -385,11 +389,14 @@ static int lookupName(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cnt++;
|
cnt++;
|
||||||
cntTab = 2;
|
hit = 1;
|
||||||
|
}else if( cnt>0 ){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cntTab++;
|
||||||
pMatch = pItem;
|
pMatch = pItem;
|
||||||
pExpr->iColumn = j;
|
pExpr->iColumn = j;
|
||||||
pEList->a[j].fg.bUsed = 1;
|
pEList->a[j].fg.bUsed = 1;
|
||||||
hit = 1;
|
|
||||||
if( pEList->a[j].fg.bUsingTerm ) break;
|
if( pEList->a[j].fg.bUsingTerm ) break;
|
||||||
}
|
}
|
||||||
if( hit || zTab==0 ) continue;
|
if( hit || zTab==0 ) continue;
|
||||||
@@ -584,10 +591,10 @@ static int lookupName(
|
|||||||
&& pMatch
|
&& pMatch
|
||||||
&& (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0
|
&& (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0
|
||||||
&& sqlite3IsRowid(zCol)
|
&& sqlite3IsRowid(zCol)
|
||||||
&& ALWAYS(VisibleRowid(pMatch->pTab))
|
&& ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom)
|
||||||
){
|
){
|
||||||
cnt = 1;
|
cnt = 1;
|
||||||
pExpr->iColumn = -1;
|
if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1;
|
||||||
pExpr->affExpr = SQLITE_AFF_INTEGER;
|
pExpr->affExpr = SQLITE_AFF_INTEGER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5284,7 +5284,7 @@ int sqlite3MatchEName(
|
|||||||
const char*,
|
const char*,
|
||||||
const char*,
|
const char*,
|
||||||
const char*,
|
const char*,
|
||||||
int
|
int*
|
||||||
);
|
);
|
||||||
Bitmask sqlite3ExprColUsed(Expr*);
|
Bitmask sqlite3ExprColUsed(Expr*);
|
||||||
u8 sqlite3StrIHash(const char*);
|
u8 sqlite3StrIHash(const char*);
|
||||||
|
|||||||
@@ -176,6 +176,7 @@ do_execsql_test 8.1 {
|
|||||||
SELECT x3.oid FROM x1 JOIN (x2 JOIN x3 ON c='c')
|
SELECT x3.oid FROM x1 JOIN (x2 JOIN x3 ON c='c')
|
||||||
} 43
|
} 43
|
||||||
|
|
||||||
|
breakpoint
|
||||||
do_execsql_test 8.2 {
|
do_execsql_test 8.2 {
|
||||||
SELECT x3.rowid FROM x1 JOIN (x2 JOIN x3 ON c='c')
|
SELECT x3.rowid FROM x1 JOIN (x2 JOIN x3 ON c='c')
|
||||||
} {hello}
|
} {hello}
|
||||||
@@ -195,18 +196,31 @@ do_execsql_test 9.0 {
|
|||||||
|
|
||||||
CREATE TABLE wo1(a PRIMARY KEY, b) WITHOUT ROWID;
|
CREATE TABLE wo1(a PRIMARY KEY, b) WITHOUT ROWID;
|
||||||
CREATE TABLE wo2(a PRIMARY KEY, rowid) WITHOUT ROWID;
|
CREATE TABLE wo2(a PRIMARY KEY, rowid) WITHOUT ROWID;
|
||||||
|
CREATE TABLE wo3(a PRIMARY KEY, b) WITHOUT ROWID;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Should an error.
|
|
||||||
do_catchsql_test 9.1 {
|
do_catchsql_test 9.1 {
|
||||||
|
SELECT rowid FROM wo1, x1, x2;
|
||||||
|
} {1 {no such column: rowid}}
|
||||||
|
do_catchsql_test 9.2 {
|
||||||
|
SELECT rowid FROM wo1, (x1, x2);
|
||||||
|
} {1 {no such column: rowid}}
|
||||||
|
do_catchsql_test 9.3 {
|
||||||
SELECT rowid FROM wo1 JOIN (x1 JOIN x2);
|
SELECT rowid FROM wo1 JOIN (x1 JOIN x2);
|
||||||
} {1 {no such column: rowid}}
|
} {1 {no such column: rowid}}
|
||||||
|
do_catchsql_test 9.4 {
|
||||||
# Should not be an error.
|
SELECT a FROM wo1, x1, x2;
|
||||||
do_catchsql_test 9.2 {
|
} {1 {ambiguous column name: a}}
|
||||||
|
do_catchsql_test 9.5 {
|
||||||
SELECT rowid FROM x1 JOIN (x2 JOIN wo2);
|
SELECT rowid FROM x1 JOIN (x2 JOIN wo2);
|
||||||
} {0 {}}
|
} {0 {}}
|
||||||
|
|
||||||
|
do_catchsql_test 9.6 {
|
||||||
|
SELECT _rowid_ FROM wo1 JOIN (wo3 JOIN x3)
|
||||||
|
} {0 {}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user