From 81b70d97eb3ccf25d8fec5544009e6ebe9225b4a Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 15 Sep 2023 18:36:51 +0000 Subject: [PATCH 1/6] Allow expressions like ".rowid" to refer to implicit rowid columns of tables in nested FROM clauses. FossilOrigin-Name: 59a1bbc69f5dbb33418fa4b383393fb13a46bc1e531577da8ad54ae2fad5a10e --- manifest | 26 +++++++++-------- manifest.uuid | 2 +- src/expr.c | 21 ++++++++++++++ src/resolve.c | 35 +++++++++++++++------- src/select.c | 68 +++++++++++++++++++++++++++---------------- src/sqliteInt.h | 5 +++- test/joinH.test | 77 +++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 185 insertions(+), 49 deletions(-) diff --git a/manifest b/manifest index 2cc282e161..d0c2ef5017 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\stry\sto\sconvert\sa\sdouble\sinto\san\sunsigned\s64-bit\sinteger,\sas\sthat\sdoes\nnot\swork\son\sall\splatforms.\s\sA\sdouble\scan\sonly\sbe\sconverted\sinto\sa\ssigned\n64-bit\sinteger. -D 2023-09-15T10:24:29.345 +C Allow\sexpressions\slike\s".rowid"\sto\srefer\sto\simplicit\srowid\scolumns\sof\stables\sin\snested\sFROM\sclauses. +D 2023-09-15T18:36:51.501 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -660,7 +660,7 @@ F src/date.c eebc54a00e888d3c56147779e9f361b77d62fd69ff2008c5373946aa1ba1d574 F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387 F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500 -F src/expr.c c8c436f3c71179d1ecafc69623d562a1da006c2641dc0ef2884028317c7c584c +F src/expr.c 9902bebcc9fa2b2c4cc94b7aa5615afe1affc98a986553aa7b239971c54ddea8 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c a7fcbf7e66d14dbb73cf49f31489ebf66d0e6006c62b95246924a3bae9f37b36 F src/func.c 154f08966f8a3a7cad6c438205df1abf58fb2826961a0683e82e120fa647e84c @@ -708,14 +708,14 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c 80548297dc0e1fb3139cdebffb5a1bcac3dfac66d791012dd74838e70445072d F src/printf.c e3ba080e2f409f9bfcc8d34724e6fc160e9c718dc92d0548f6b71b8b6f860ce2 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c -F src/resolve.c 37953a5f36c60bea413c3c04efcd433b6177009f508ef2ace0494728912fe2e9 +F src/resolve.c f31aab54a4bcb1a3e592daa6b657b7d3a725e40bf764a652dc175006ed4eead2 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c e9fb48546ab1882639a3a960383f6342dddb776c0227615f8e19de51f0102f68 +F src/select.c 5e9ff0eb38e5341780a70e3a39ea1d447c237552d1f552416dc605c123bf2acd F src/shell.c.in 62708bea44d4e43aa7b1270ed422d1d29e82297924d4e0f223c39336a3f582f8 F src/sqlite.h.in 931a58d119d5cf87110648f39fa0bb9f1738b0068cb68250d893304a471bd6c0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 2f30b2671f4c03cd27a43f039e11251391066c97d11385f5f963bb40b03038ac -F src/sqliteInt.h 0c33d256c0f7de824c7cef1aef14b66c94e4f0de77d598284048e73be6bb4f39 +F src/sqliteInt.h 6cac7a6d674ea44fa867d929786ddec86df9be64c24d59afbf15c7bac671067c F src/sqliteLimit.h 33b1c9baba578d34efe7dfdb43193b366111cdf41476b1e82699e14c11ee1fb6 F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1290,7 +1290,7 @@ F test/joinC.test 1f1a602c2127f55f136e2cbd3bf2d26546614bf8cffe5902ec1ac9c07f87f2 F test/joinD.test 2ce62e7353a0702ca5e70008faf319c1d4686aa19fba34275c6d1da0e960be28 F test/joinE.test d5d182f3812771e2c0d97c9dcf5dbe4c41c8e21c82560e59358731c4a3981d6b F test/joinF.test 53dd66158806823ea680dd7543b5406af151b5aafa5cd06a7f3231cd94938127 -F test/joinH.test c9550bb6a0257cf99668a28485bb309bac542081702e89261b95542ab5f676b1 +F test/joinH.test 44c51631e487a55902b2ed05706cad19c3ecdd86b7e1c7c8aa84457cec564d11 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -2121,9 +2121,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 858fa236f8b673eb03cf2242e8202cd33ae1f13a43b59bdbb2eecdb21d42ef55 0ab05871ba36e2a0eddfbc700c1d39891c54c453727a4effcdac3327efec163b -R 471f1110fdf5d26a5080351103b3b730 -T +closed 0ab05871ba36e2a0eddfbc700c1d39891c54c453727a4effcdac3327efec163b -U drh -Z 5b5a1b021f1cd0ac8b138bf678d74c57 +P ce339046416e9ddeffe77f71a8bfb8c5b302160c3207f919aebd62902618ed59 +R bcfd521e8d34de98592bf4e489ebb783 +T *branch * nested-from-rowid-expansion +T *sym-nested-from-rowid-expansion * +T -sym-trunk * +U dan +Z dee6d86baf948e05aa8b2bb5ee3449dc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a478c84dce..eec8fc8c40 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ce339046416e9ddeffe77f71a8bfb8c5b302160c3207f919aebd62902618ed59 \ No newline at end of file +59a1bbc69f5dbb33418fa4b383393fb13a46bc1e531577da8ad54ae2fad5a10e \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 9f876e6107..63c5a8faa9 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2694,6 +2694,27 @@ int sqlite3IsRowid(const char *z){ return 0; } +/* +** Return a pointer to a buffer containing a usable rowid alias for table +** pTab. An alias is usable if there is not an explicit user-defined column +** of the same name. +*/ +const char *sqlite3RowidAlias(Table *pTab){ + const char *azOpt[] = {"_ROWID_", "ROWID", "OID"}; + int ii; + assert( VisibleRowid(pTab) ); + for(ii=0; iinCol; iCol++){ + if( sqlite3_stricmp(azOpt[ii], pTab->aCol[iCol].zCnName)==0 ) break; + } + if( iCol==pTab->nCol ){ + return azOpt[ii]; + } + } + return 0; +} + /* ** pX is the RHS of an IN operator. If pX is a SELECT statement ** that can be simplified to a direct table access, then return diff --git a/src/resolve.c b/src/resolve.c index 7fc0151ad2..20bce29a21 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.". 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; jnExpr; j++){ - if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){ + if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb, cnt==0) ){ continue; } if( cnt>0 ){ diff --git a/src/select.c b/src/select.c index 90b284036c..edd45b44c1 100644 --- a/src/select.c +++ b/src/select.c @@ -6114,6 +6114,7 @@ static int selectExpander(Walker *pWalker, Select *p){ char *zTName = 0; /* text of name of TABLE */ int iErrOfst; if( pE->op==TK_DOT ){ + assert( (selFlags & SF_NestedFrom)==0 ); assert( pE->pLeft!=0 ); assert( !ExprHasProperty(pE->pLeft, EP_IntValue) ); zTName = pE->pLeft->u.zToken; @@ -6124,6 +6125,7 @@ static int selectExpander(Walker *pWalker, Select *p){ iErrOfst = pE->w.iOfst; } for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ + int nAdd; /* Number of cols including rowid */ Table *pTab = pFrom->pTab; /* Table for this data source */ ExprList *pNestedFrom; /* Result-set of a nested FROM clause */ char *zTabName; /* AS name for this data source */ @@ -6141,6 +6143,7 @@ static int selectExpander(Walker *pWalker, Select *p){ pNestedFrom = pFrom->pSelect->pEList; assert( pNestedFrom!=0 ); assert( pNestedFrom->nExpr==pTab->nCol ); + assert( VisibleRowid(pTab)==0 ); }else{ if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ continue; @@ -6171,33 +6174,48 @@ static int selectExpander(Walker *pWalker, Select *p){ }else{ pUsing = 0; } - for(j=0; jnCol; j++){ - char *zName = pTab->aCol[j].zCnName; + + nAdd = pTab->nCol + (VisibleRowid(pTab) && (selFlags&SF_NestedFrom)); + for(j=0; ja[j], 0, zTName, 0)==0 - ){ - continue; - } + if( j==pTab->nCol ){ + zName = sqlite3RowidAlias(pTab); + if( zName==0 ) continue; + }else{ + zName = pTab->aCol[j].zCnName; - /* If a column is marked as 'hidden', omit it from the expanded - ** result-set list unless the SELECT has the SF_IncludeHidden - ** bit set. - */ - if( (p->selFlags & SF_IncludeHidden)==0 - && IsHiddenColumn(&pTab->aCol[j]) - ){ - continue; - } - if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 - && zTName==0 - && (selFlags & (SF_NestedFrom))==0 - ){ - continue; + /* If pTab is actually an SF_NestedFrom sub-select, do not + ** expand any ENAME_ROWID columns. */ + if( pNestedFrom && pNestedFrom->a[j].fg.eEName==ENAME_ROWID ){ + continue; + } + + if( zTName + && pNestedFrom + && sqlite3MatchEName(&pNestedFrom->a[j], 0, zTName, 0, 0)==0 + ){ + continue; + } + + /* If a column is marked as 'hidden', omit it from the expanded + ** result-set list unless the SELECT has the SF_IncludeHidden + ** bit set. + */ + if( (p->selFlags & SF_IncludeHidden)==0 + && IsHiddenColumn(&pTab->aCol[j]) + ){ + continue; + } + if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 + && zTName==0 + && (selFlags & (SF_NestedFrom))==0 + ){ + continue; + } } + assert( zName ); tableSeen = 1; if( i>0 && zTName==0 && (selFlags & SF_NestedFrom)==0 ){ @@ -6247,11 +6265,11 @@ static int selectExpander(Walker *pWalker, Select *p){ zSchemaName, zTabName, zName); testcase( pX->zEName==0 ); } - pX->fg.eEName = ENAME_TAB; + pX->fg.eEName = (j==pTab->nCol ? ENAME_ROWID : ENAME_TAB); if( (pFrom->fg.isUsing && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0) || (pUsing && sqlite3IdListIndex(pUsing, zName)>=0) - || (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 + || (jnCol && (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)) ){ pX->fg.bNoExpand = 1; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 31eac37493..b8473b2d1d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3181,6 +3181,7 @@ struct ExprList { #define ENAME_NAME 0 /* The AS clause of a result set */ #define ENAME_SPAN 1 /* Complete text of the result set expression */ #define ENAME_TAB 2 /* "DB.TABLE.NAME" for the result set */ +#define ENAME_ROWID 3 /* "DB.TABLE._rowid_" for * expansion of rowid */ /* ** An instance of this structure can hold a simple list of identifiers, @@ -5010,6 +5011,7 @@ int sqlite3ExprIsInteger(const Expr*, int*); int sqlite3ExprCanBeNull(const Expr*); int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); int sqlite3IsRowid(const char*); +const char *sqlite3RowidAlias(Table *pTab); void sqlite3GenerateRowDelete( Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int); void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); @@ -5281,7 +5283,8 @@ int sqlite3MatchEName( const struct ExprList_item*, const char*, const char*, - const char* + const char*, + int ); Bitmask sqlite3ExprColUsed(Expr*); u8 sqlite3StrIHash(const char*); diff --git a/test/joinH.test b/test/joinH.test index edba26de2d..3c1a55e8e8 100644 --- a/test/joinH.test +++ b/test/joinH.test @@ -132,4 +132,81 @@ do_execsql_test 6.0 { do_execsql_test 6.1 { SELECT * FROM t1 LEFT JOIN t2 ON true WHERE CASE WHEN t2.b THEN 0 ELSE 1 END; } {3 NULL} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 7.0 { + CREATE TABLE t1(a, b); + CREATE TABLE t2(c); + CREATE TABLE t3(d); + + INSERT INTO t1 VALUES ('a', 'a'); + INSERT INTO t2 VALUES ('ddd'); + INSERT INTO t3 VALUES(1234); +} + +do_execsql_test 7.1 { + SELECT t2.rowid FROM t1 JOIN (t2 JOIN t3); +} {1} + +do_execsql_test 7.1 { + UPDATE t1 SET b = t2.rowid FROM t2, t3; +} + +do_execsql_test 7.2 { + SELECT * FROM t1 +} {a 1} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 8.0 { + CREATE TABLE x1(a INTEGER PRIMARY KEY, b); + CREATE TABLE x2(c, d); + CREATE TABLE x3(rowid, _rowid_); + + CREATE TABLE x4(rowid, _rowid_, oid); + + INSERT INTO x1 VALUES(1000, 'thousand'); + INSERT INTO x2 VALUES('c', 'd'); + INSERT INTO x3(oid, rowid, _rowid_) VALUES(43, 'hello', 'world'); + INSERT INTO x4(oid, rowid, _rowid_) VALUES('forty three', 'hello', 'world'); +} + +do_execsql_test 8.1 { + SELECT x3.oid FROM x1 JOIN (x2 JOIN x3 ON c='c') +} 43 + +do_execsql_test 8.2 { + SELECT x3.rowid FROM x1 JOIN (x2 JOIN x3 ON c='c') +} {hello} + +do_execsql_test 8.3 { + SELECT x4.oid FROM x1 JOIN (x2 JOIN x4 ON c='c') +} {{forty three}} + + +#--------------------------------------------------------------------- +# +reset_db +do_execsql_test 9.0 { + CREATE TABLE x1(a); + CREATE TABLE x2(b); + CREATE TABLE x3(c); + + CREATE TABLE wo1(a PRIMARY KEY, b) WITHOUT ROWID; + CREATE TABLE wo2(a PRIMARY KEY, rowid) WITHOUT ROWID; +} + +# Should an error. +do_catchsql_test 9.1 { + SELECT rowid FROM wo1 JOIN (x1 JOIN x2); +} {1 {no such column: rowid}} + +# Should not be an error. +do_catchsql_test 9.2 { + SELECT rowid FROM x1 JOIN (x2 JOIN wo2); +} {0 {}} + + finish_test + From 63702bccaaf87a1af36fc714cc496645348bf406 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 15 Sep 2023 20:57:05 +0000 Subject: [PATCH 2/6] Fix resolution of unqualified "rowid" identifiers in queries with nested joins. FossilOrigin-Name: bbcbd3d537d6790373d97f59386b8ce7fa2177db572af0f1babe058a76e25cc3 --- manifest | 19 ++++++------- manifest.uuid | 2 +- src/resolve.c | 71 +++++++++++++++++++++++++++---------------------- src/sqliteInt.h | 2 +- test/joinH.test | 22 ++++++++++++--- 5 files changed, 67 insertions(+), 49 deletions(-) diff --git a/manifest b/manifest index d0c2ef5017..b2ddfc0821 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sexpressions\slike\s".rowid"\sto\srefer\sto\simplicit\srowid\scolumns\sof\stables\sin\snested\sFROM\sclauses. -D 2023-09-15T18:36:51.501 +C Fix\sresolution\sof\sunqualified\s"rowid"\sidentifiers\sin\squeries\swith\snested\sjoins. +D 2023-09-15T20:57:05.776 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -708,14 +708,14 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c 80548297dc0e1fb3139cdebffb5a1bcac3dfac66d791012dd74838e70445072d F src/printf.c e3ba080e2f409f9bfcc8d34724e6fc160e9c718dc92d0548f6b71b8b6f860ce2 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c -F src/resolve.c f31aab54a4bcb1a3e592daa6b657b7d3a725e40bf764a652dc175006ed4eead2 +F src/resolve.c 1cbb3dacd41882dabe07209242d015f100d36cfb685235278b1d4e15711017b7 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 5e9ff0eb38e5341780a70e3a39ea1d447c237552d1f552416dc605c123bf2acd F src/shell.c.in 62708bea44d4e43aa7b1270ed422d1d29e82297924d4e0f223c39336a3f582f8 F src/sqlite.h.in 931a58d119d5cf87110648f39fa0bb9f1738b0068cb68250d893304a471bd6c0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 2f30b2671f4c03cd27a43f039e11251391066c97d11385f5f963bb40b03038ac -F src/sqliteInt.h 6cac7a6d674ea44fa867d929786ddec86df9be64c24d59afbf15c7bac671067c +F src/sqliteInt.h f2d713fac835f32b131d8a334595b0c471ede3796dab527c705d2b03c32d14e9 F src/sqliteLimit.h 33b1c9baba578d34efe7dfdb43193b366111cdf41476b1e82699e14c11ee1fb6 F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1290,7 +1290,7 @@ F test/joinC.test 1f1a602c2127f55f136e2cbd3bf2d26546614bf8cffe5902ec1ac9c07f87f2 F test/joinD.test 2ce62e7353a0702ca5e70008faf319c1d4686aa19fba34275c6d1da0e960be28 F test/joinE.test d5d182f3812771e2c0d97c9dcf5dbe4c41c8e21c82560e59358731c4a3981d6b F test/joinF.test 53dd66158806823ea680dd7543b5406af151b5aafa5cd06a7f3231cd94938127 -F test/joinH.test 44c51631e487a55902b2ed05706cad19c3ecdd86b7e1c7c8aa84457cec564d11 +F test/joinH.test 832a33079ee8fba7e33fa5ac77c481b3fd8399ba16362d4524a0be22a060b9f2 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -2121,11 +2121,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ce339046416e9ddeffe77f71a8bfb8c5b302160c3207f919aebd62902618ed59 -R bcfd521e8d34de98592bf4e489ebb783 -T *branch * nested-from-rowid-expansion -T *sym-nested-from-rowid-expansion * -T -sym-trunk * +P 59a1bbc69f5dbb33418fa4b383393fb13a46bc1e531577da8ad54ae2fad5a10e +R 790b7202228cf2f5b7a7a80533c697dd U dan -Z dee6d86baf948e05aa8b2bb5ee3449dc +Z ce4b0349e1c5a42e7e7210175df9fc25 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index eec8fc8c40..2c2a02ac67 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -59a1bbc69f5dbb33418fa4b383393fb13a46bc1e531577da8ad54ae2fad5a10e \ No newline at end of file +bbcbd3d537d6790373d97f59386b8ce7fa2177db572af0f1babe058a76e25cc3 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 20bce29a21..6935480ced 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -117,22 +117,23 @@ static void resolveAlias( ** 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.". 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. +** argument matches if zCol is a rowid alias. If it is not NULL, (*pbRowid) +** is set to 1 if there is this kind of match. */ int sqlite3MatchEName( const struct ExprList_item *pItem, const char *zCol, const char *zTab, const char *zDb, - int bRowidOk + int *pbRowid ){ int n; const char *zSpan; 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; } + assert( pbRowid==0 || *pbRowid==0 ); zSpan = pItem->zEName; for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} 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_ROWID && sqlite3IsRowid(zCol)==0 ) return 0; } + if( eEName==ENAME_ROWID ) *pbRowid = 1; return 1; } @@ -357,39 +359,44 @@ static int lookupName( assert( pEList!=0 ); assert( pEList->nExpr==pTab->nCol ); for(j=0; jnExpr; 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; } - 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( bRowid==0 ){ + 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++; + hit = 1; + }else if( cnt>0 ){ + continue; } - cnt++; - cntTab = 2; + cntTab++; pMatch = pItem; pExpr->iColumn = j; pEList->a[j].fg.bUsed = 1; - hit = 1; if( pEList->a[j].fg.bUsingTerm ) break; } if( hit || zTab==0 ) continue; @@ -584,10 +591,10 @@ static int lookupName( && pMatch && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 && sqlite3IsRowid(zCol) - && ALWAYS(VisibleRowid(pMatch->pTab)) + && ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom) ){ cnt = 1; - pExpr->iColumn = -1; + if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1; pExpr->affExpr = SQLITE_AFF_INTEGER; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index b8473b2d1d..225e54800b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -5284,7 +5284,7 @@ int sqlite3MatchEName( const char*, const char*, const char*, - int + int* ); Bitmask sqlite3ExprColUsed(Expr*); u8 sqlite3StrIHash(const char*); diff --git a/test/joinH.test b/test/joinH.test index 3c1a55e8e8..1e1d322a28 100644 --- a/test/joinH.test +++ b/test/joinH.test @@ -176,6 +176,7 @@ do_execsql_test 8.1 { SELECT x3.oid FROM x1 JOIN (x2 JOIN x3 ON c='c') } 43 +breakpoint do_execsql_test 8.2 { SELECT x3.rowid FROM x1 JOIN (x2 JOIN x3 ON c='c') } {hello} @@ -195,18 +196,31 @@ do_execsql_test 9.0 { CREATE TABLE wo1(a PRIMARY KEY, b) 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 { + 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); } {1 {no such column: rowid}} - -# Should not be an error. -do_catchsql_test 9.2 { +do_catchsql_test 9.4 { + SELECT a FROM wo1, x1, x2; +} {1 {ambiguous column name: a}} +do_catchsql_test 9.5 { SELECT rowid FROM x1 JOIN (x2 JOIN wo2); } {0 {}} +do_catchsql_test 9.6 { + SELECT _rowid_ FROM wo1 JOIN (wo3 JOIN x3) +} {0 {}} + + + finish_test From 2e8edc1d45d9b7b64cc2fa0539c5b9931c8603d2 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 16 Sep 2023 14:42:18 +0000 Subject: [PATCH 3/6] Further tests and assert() statements for the change on this branch. FossilOrigin-Name: 1c202d540ac362bfc747a9f8472e83c9d7614e38467f8b48787a669fb34664ba --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/resolve.c | 7 ++++++- test/joinH.test | 41 +++++++++++++++++++++++++++++++++++------ 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index b2ddfc0821..cd7c3be9f9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sresolution\sof\sunqualified\s"rowid"\sidentifiers\sin\squeries\swith\snested\sjoins. -D 2023-09-15T20:57:05.776 +C Further\stests\sand\sassert()\sstatements\sfor\sthe\schange\son\sthis\sbranch. +D 2023-09-16T14:42:18.058 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -708,7 +708,7 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c 80548297dc0e1fb3139cdebffb5a1bcac3dfac66d791012dd74838e70445072d F src/printf.c e3ba080e2f409f9bfcc8d34724e6fc160e9c718dc92d0548f6b71b8b6f860ce2 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c -F src/resolve.c 1cbb3dacd41882dabe07209242d015f100d36cfb685235278b1d4e15711017b7 +F src/resolve.c 2aaa1d5c69f40529951efe4901263e2b82bc95e3e3248088a7a4c887db740bdc F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 5e9ff0eb38e5341780a70e3a39ea1d447c237552d1f552416dc605c123bf2acd F src/shell.c.in 62708bea44d4e43aa7b1270ed422d1d29e82297924d4e0f223c39336a3f582f8 @@ -1290,7 +1290,7 @@ F test/joinC.test 1f1a602c2127f55f136e2cbd3bf2d26546614bf8cffe5902ec1ac9c07f87f2 F test/joinD.test 2ce62e7353a0702ca5e70008faf319c1d4686aa19fba34275c6d1da0e960be28 F test/joinE.test d5d182f3812771e2c0d97c9dcf5dbe4c41c8e21c82560e59358731c4a3981d6b F test/joinF.test 53dd66158806823ea680dd7543b5406af151b5aafa5cd06a7f3231cd94938127 -F test/joinH.test 832a33079ee8fba7e33fa5ac77c481b3fd8399ba16362d4524a0be22a060b9f2 +F test/joinH.test 5f6107246b8509f9df4745fbdc2107a16f07594770a5c473a25f6c7f672edd86 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -2121,8 +2121,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 59a1bbc69f5dbb33418fa4b383393fb13a46bc1e531577da8ad54ae2fad5a10e -R 790b7202228cf2f5b7a7a80533c697dd +P bbcbd3d537d6790373d97f59386b8ce7fa2177db572af0f1babe058a76e25cc3 +R bf57b361beb0f7cbd2e152c6af93c51b U dan -Z ce4b0349e1c5a42e7e7210175df9fc25 +Z 9359045b06de790036a380b27c8df205 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2c2a02ac67..bbf6a5e828 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bbcbd3d537d6790373d97f59386b8ce7fa2177db572af0f1babe058a76e25cc3 \ No newline at end of file +1c202d540ac362bfc747a9f8472e83c9d7614e38467f8b48787a669fb34664ba \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 6935480ced..d843290343 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -282,7 +282,7 @@ static int lookupName( ){ int i, j; /* Loop counters */ int cnt = 0; /* Number of matching column names */ - int cntTab = 0; /* Number of matching table names */ + int cntTab = 0; /* Number of potential "rowid" matches */ int nSubquery = 0; /* How many levels of subquery */ sqlite3 *db = pParse->db; /* The database connection */ SrcItem *pItem; /* Use for looping over pSrcList items */ @@ -391,12 +391,17 @@ static int lookupName( cnt++; hit = 1; }else if( cnt>0 ){ + /* This is a potential rowid match, but there has already been + ** a real match found. So this can be ignored. */ continue; } cntTab++; pMatch = pItem; pExpr->iColumn = j; pEList->a[j].fg.bUsed = 1; + + /* rowid cannot be part of a USING clause - assert() this. */ + assert( bRowid==0 || pEList->a[j].fg.bUsingTerm==0 ); if( pEList->a[j].fg.bUsingTerm ) break; } if( hit || zTab==0 ) continue; diff --git a/test/joinH.test b/test/joinH.test index 1e1d322a28..027f0a3999 100644 --- a/test/joinH.test +++ b/test/joinH.test @@ -211,15 +211,44 @@ do_catchsql_test 9.3 { do_catchsql_test 9.4 { SELECT a FROM wo1, x1, x2; } {1 {ambiguous column name: a}} + + +# It is not possible to use "rowid" in a USING clause. +# do_catchsql_test 9.5 { - SELECT rowid FROM x1 JOIN (x2 JOIN wo2); -} {0 {}} - + SELECT * FROM x1 JOIN x2 USING (rowid); +} {1 {cannot join using column rowid - column not present in both tables}} do_catchsql_test 9.6 { + SELECT * FROM wo2 JOIN x2 USING (rowid); +} {1 {cannot join using column rowid - column not present in both tables}} + +# "rowid" columns are not matched by NATURAL JOIN. If they were, then +# the SELECT below would return zero rows. +do_execsql_test 9.7 { + INSERT INTO x1(rowid, a) VALUES(101, 'A'); + INSERT INTO x2(rowid, b) VALUES(55, 'B'); + SELECT * FROM x1 NATURAL JOIN x2; +} {A B} + +do_execsql_test 9.8 { + INSERT INTO wo1(a, b) VALUES('mya', 'myb'); + INSERT INTO wo2(a, rowid) VALUES('mypk', 'myrowid'); + INSERT INTO wo3(a, b) VALUES('MYA', 'MYB'); + INSERT INTO x3(rowid, c) VALUES(99, 'x3B'); +} + +do_catchsql_test 9.8 { + SELECT rowid FROM x1 JOIN (x2 JOIN wo2); +} {0 myrowid} +do_catchsql_test 9.9 { SELECT _rowid_ FROM wo1 JOIN (wo3 JOIN x3) -} {0 {}} - - +} {0 99} +do_catchsql_test 9.10 { + SELECT oid FROM wo1 JOIN (wo3 JOIN x3) +} {0 99} +do_catchsql_test 9.11 { + SELECT oid FROM wo2 JOIN (wo3 JOIN x3) +} {0 99} finish_test From 5ddf0cbe25422d328dd862ccd3d2c7962ba3ab60 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 16 Sep 2023 16:12:10 +0000 Subject: [PATCH 4/6] Fix a harmless compiler warning. FossilOrigin-Name: 9e9ff4ca3a205d0b599634782a5ad389fbe4823663550f48c54ca35dbc660dc7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index cd7c3be9f9..5bdbddef55 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\stests\sand\sassert()\sstatements\sfor\sthe\schange\son\sthis\sbranch. -D 2023-09-16T14:42:18.058 +C Fix\sa\sharmless\scompiler\swarning. +D 2023-09-16T16:12:10.624 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -710,7 +710,7 @@ F src/printf.c e3ba080e2f409f9bfcc8d34724e6fc160e9c718dc92d0548f6b71b8b6f860ce2 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 2aaa1d5c69f40529951efe4901263e2b82bc95e3e3248088a7a4c887db740bdc F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 5e9ff0eb38e5341780a70e3a39ea1d447c237552d1f552416dc605c123bf2acd +F src/select.c 41e00717491a5f89d37e099b89a8cc6199fa8764dc795709a386b300ae122317 F src/shell.c.in 62708bea44d4e43aa7b1270ed422d1d29e82297924d4e0f223c39336a3f582f8 F src/sqlite.h.in 931a58d119d5cf87110648f39fa0bb9f1738b0068cb68250d893304a471bd6c0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -2121,8 +2121,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bbcbd3d537d6790373d97f59386b8ce7fa2177db572af0f1babe058a76e25cc3 -R bf57b361beb0f7cbd2e152c6af93c51b -U dan -Z 9359045b06de790036a380b27c8df205 +P 1c202d540ac362bfc747a9f8472e83c9d7614e38467f8b48787a669fb34664ba +R 9762fb2f5a5bf9ebb34dd3cffd79f3dd +U drh +Z a20669ebfd41402e15dd4d0850b27630 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bbf6a5e828..6290ce9efc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1c202d540ac362bfc747a9f8472e83c9d7614e38467f8b48787a669fb34664ba \ No newline at end of file +9e9ff4ca3a205d0b599634782a5ad389fbe4823663550f48c54ca35dbc660dc7 \ No newline at end of file diff --git a/src/select.c b/src/select.c index edd45b44c1..775521718d 100644 --- a/src/select.c +++ b/src/select.c @@ -6177,7 +6177,7 @@ static int selectExpander(Walker *pWalker, Select *p){ nAdd = pTab->nCol + (VisibleRowid(pTab) && (selFlags&SF_NestedFrom)); for(j=0; jnCol ){ From 5bd96b24465abc315b07e8003ea2a03d6bee3210 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 16 Sep 2023 16:23:20 +0000 Subject: [PATCH 5/6] Fix minor code indentation inconsistencies. No function changes. FossilOrigin-Name: 05107a0ae1456b746d3119af68d39532fad23a7eef88c09a9ef46ab7f8da4b9d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 5bdbddef55..9996c0606c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\scompiler\swarning. -D 2023-09-16T16:12:10.624 +C Fix\sminor\scode\sindentation\sinconsistencies.\s\sNo\sfunction\schanges. +D 2023-09-16T16:23:20.928 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -710,7 +710,7 @@ F src/printf.c e3ba080e2f409f9bfcc8d34724e6fc160e9c718dc92d0548f6b71b8b6f860ce2 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 2aaa1d5c69f40529951efe4901263e2b82bc95e3e3248088a7a4c887db740bdc F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 41e00717491a5f89d37e099b89a8cc6199fa8764dc795709a386b300ae122317 +F src/select.c 7f9155185be78902818b21c2cd3e33f01b4306279a15d6719eb1bbb9779034aa F src/shell.c.in 62708bea44d4e43aa7b1270ed422d1d29e82297924d4e0f223c39336a3f582f8 F src/sqlite.h.in 931a58d119d5cf87110648f39fa0bb9f1738b0068cb68250d893304a471bd6c0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -2121,8 +2121,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1c202d540ac362bfc747a9f8472e83c9d7614e38467f8b48787a669fb34664ba -R 9762fb2f5a5bf9ebb34dd3cffd79f3dd +P 9e9ff4ca3a205d0b599634782a5ad389fbe4823663550f48c54ca35dbc660dc7 +R 5fdbb991511b12e8d6117dcb5b9dc4a0 U drh -Z a20669ebfd41402e15dd4d0850b27630 +Z 8b66894d46fa8ad371272d9e9ecf2ba6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6290ce9efc..9fef7ce54d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9e9ff4ca3a205d0b599634782a5ad389fbe4823663550f48c54ca35dbc660dc7 \ No newline at end of file +05107a0ae1456b746d3119af68d39532fad23a7eef88c09a9ef46ab7f8da4b9d \ No newline at end of file diff --git a/src/select.c b/src/select.c index 775521718d..a55545d513 100644 --- a/src/select.c +++ b/src/select.c @@ -6193,9 +6193,9 @@ static int selectExpander(Walker *pWalker, Select *p){ } if( zTName - && pNestedFrom - && sqlite3MatchEName(&pNestedFrom->a[j], 0, zTName, 0, 0)==0 - ){ + && pNestedFrom + && sqlite3MatchEName(&pNestedFrom->a[j], 0, zTName, 0, 0)==0 + ){ continue; } @@ -6204,14 +6204,14 @@ static int selectExpander(Walker *pWalker, Select *p){ ** bit set. */ if( (p->selFlags & SF_IncludeHidden)==0 - && IsHiddenColumn(&pTab->aCol[j]) - ){ + && IsHiddenColumn(&pTab->aCol[j]) + ){ continue; } if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 - && zTName==0 - && (selFlags & (SF_NestedFrom))==0 - ){ + && zTName==0 + && (selFlags & (SF_NestedFrom))==0 + ){ continue; } } From a91fe453399ddc836e412a5e8f6473f8a3e68066 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 16 Sep 2023 16:39:27 +0000 Subject: [PATCH 6/6] Add a NEVER() to an unreachable branch. FossilOrigin-Name: 6b6eb38979d68c06e382620c8813d6b67a3de02c4a7a029c84f924b9a2e380c6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9996c0606c..5225d95550 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sminor\scode\sindentation\sinconsistencies.\s\sNo\sfunction\schanges. -D 2023-09-16T16:23:20.928 +C Add\sa\sNEVER()\sto\san\sunreachable\sbranch. +D 2023-09-16T16:39:27.998 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -708,7 +708,7 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c 80548297dc0e1fb3139cdebffb5a1bcac3dfac66d791012dd74838e70445072d F src/printf.c e3ba080e2f409f9bfcc8d34724e6fc160e9c718dc92d0548f6b71b8b6f860ce2 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c -F src/resolve.c 2aaa1d5c69f40529951efe4901263e2b82bc95e3e3248088a7a4c887db740bdc +F src/resolve.c 0c3046b88901336709cd09f474303a16fc54bce13a2befcab66d0fa6b44ca869 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 7f9155185be78902818b21c2cd3e33f01b4306279a15d6719eb1bbb9779034aa F src/shell.c.in 62708bea44d4e43aa7b1270ed422d1d29e82297924d4e0f223c39336a3f582f8 @@ -2121,8 +2121,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9e9ff4ca3a205d0b599634782a5ad389fbe4823663550f48c54ca35dbc660dc7 -R 5fdbb991511b12e8d6117dcb5b9dc4a0 +P 05107a0ae1456b746d3119af68d39532fad23a7eef88c09a9ef46ab7f8da4b9d +R fc73d4482ca092115650da8908e20813 U drh -Z 8b66894d46fa8ad371272d9e9ecf2ba6 +Z 760a28483bfb77f8bee5209678f08535 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9fef7ce54d..bb06f828cf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -05107a0ae1456b746d3119af68d39532fad23a7eef88c09a9ef46ab7f8da4b9d \ No newline at end of file +6b6eb38979d68c06e382620c8813d6b67a3de02c4a7a029c84f924b9a2e380c6 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index d843290343..bd890c9f8d 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -130,7 +130,7 @@ int sqlite3MatchEName( int n; const char *zSpan; int eEName = pItem->fg.eEName; - if( eEName!=ENAME_TAB && (eEName!=ENAME_ROWID || pbRowid==0) ){ + if( eEName!=ENAME_TAB && (eEName!=ENAME_ROWID || NEVER(pbRowid==0)) ){ return 0; } assert( pbRowid==0 || *pbRowid==0 );