-C Enhance\streeview\sso\sthat\sit\sshows\sthe\scontents\sof\sON\sclauses\swhile\nthey\sare\sstill\sattached\sto\sthe\sSrcItem\sobject\sand\sbefore\sthey\sare\nmoved\sinto\sthe\sWHERE\sclause.
-D 2025-08-22T18:19:26.194
+C Remember\sif\sa\sSELECT\sstatement\scontains\san\sON\sclause.\s\sIf\sit\sdoes,\sthen\safter\nname\sresolution,\sscan\sthe\sWHERE\sclause\sto\sverify\sthat\sthe\sON\sclause\sdoes\snot\nreference\stables\sto\sits\sright.
+D 2025-08-22T19:17:44.984
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c f8d1d011aba0964ff1bdccd049d4d2c2fec217efd90d202a4bb775e926b2c25d
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
-F src/select.c 78ebf432355e820962a5001277cb43ffe3d82441c6dc9c8f0aeb0b15fbd5dd02
+F src/select.c a8dadaafc129724107aee67153732e3cd3637207993e2f60073b76344edba239
F src/shell.c.in 0636915df0dbac6c780f04959f5d1055f206fb281b2c8fc8b113fe7bfc7d44ef
F src/sqlite.h.in ebfc0358de0e18aabee7fa918f2f846894e23bebc74160fbe265c99046ee61b8
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e
-F src/sqliteInt.h a54f83985985655d1276e9e356dd6ae19b8d0b62c2abc75cc9e8f402ea141207
+F src/sqliteInt.h 7a313bfc16ea0a3b48f9b0fe69f887c971cc7884ce05969f9f02a229b8a31aae
F src/sqliteLimit.h fe70bd8983e5d317a264f2ea97473b359faf3ebb0827877a76813f5cf0cdc364
F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/where.c f2f075bd17065922235632feb368efe92a7f03d42797eb575267574fbf6d4218
F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da
F src/wherecode.c 71c5c6804b7f882dec8ec858758accae02fcfca13df3cc720f1f258e663ec7c5
-F src/whereexpr.c 78c28a8da187816d5d82049f2e343fb39f4a8e30b5bf1bda9b96cecde40ca8bd
+F src/whereexpr.c 403a44eeec1a0f0914fccc6a59376b6924bc00ef6728fe6ffce4cf3051b320fc
F src/window.c d01227141f622f24fbe36ca105fbe6ef023f9fd98f1ccd65da95f88886565db5
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test 4d7a34d328e58ca2a2d78fd76c27614a41ca7ddf4312ded9c68c04f430b3b47d
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 9ada44eb6d26532e45cdd2ed8d5707f1734d0177a13b493ff9cf070e0a992522
-R 6e697a296e1f3201fc9a77e474a82c56
+P 3e285bc117bcbfafe083709d27cca776d6ba418a9f0f58a6d4178035fba2d6ca
+R 96dd89e794ca1ca3ff39762daec8741d
+T *branch * on-clause-fix-3rd-try
+T *sym-on-clause-fix-3rd-try *
+T -sym-trunk *
U drh
-Z ad617721d7c7f540adf02c29a96cfdc3
+Z 3d2156998fed14f6409bf44712a40780
# Remove this line to create a well-formed Fossil manifest.
-3e285bc117bcbfafe083709d27cca776d6ba418a9f0f58a6d4178035fba2d6ca
+0ec8a8f64434f8cc04f02a356ecaa409ebd886566ba09c32f0fff8ebd103a609
p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->u3.pOn);
pRight->u3.pOn = 0;
pRight->fg.isOn = 1;
+ p->selFlags |= SF_OnToWhere;
}
}
return 0;
}
}
+/*
+** The xExpr and xSelect callbacks for the search of invalid ON clause terms.
+*/
+static int selectCheckOnClausesExpr(Walker *pWalker, Expr *pExpr){
+ if( pExpr->op==TK_COLUMN
+ && ExprHasProperty(pExpr, EP_OuterON|EP_InnerON)
+ ){
+ if( pExpr->w.iJoin<pExpr->iTable ){
+ if( ExprHasProperty(pExpr, EP_OuterON) || pWalker->eCode ){
+ sqlite3ErrorMsg(pWalker->pParse,
+ "ON clause references tables to its right");
+ return WRC_Abort;
+ }
+ }
+ }
+ return WRC_Continue;
+}
+static int selectCheckOnClausesSelect(Walker *pWalker, Select *pSelect){
+ UNUSED_PARAMETER(pWalker);
+ if( (pSelect->selFlags & SF_OnToWhere)==0 ){
+ return WRC_Prune;
+ }else{
+ return WRC_Continue;
+ }
+}
+
+/*
+** Check all ON clauses in pSelect to verify that they do not reference
+** columns to the right.
+*/
+static void selectCheckOnClauses(Parse *pParse, Select *pSelect){
+ Walker w;
+
+ assert( pSelect->selFlags & SF_OnToWhere );
+ assert( pSelect->pSrc!=0 && pSelect->pSrc->nSrc>=2 );
+ memset(&w, 0, sizeof(w));
+ w.pParse = pParse;
+ w.eCode = (pSelect->pSrc->a[0].fg.jointype & JT_LTORJ)!=0;
+ w.xExprCallback = selectCheckOnClausesExpr;
+ w.xSelectCallback = selectCheckOnClausesSelect;
+ sqlite3WalkSelect(&w, pSelect);
+ pSelect->selFlags &= ~SF_OnToWhere;
+}
+
/*
** Generate byte-code for the SELECT statement given in the p argument.
**
}
#endif
+ /* If the SELECT statement contains ON clauses that were moved into
+ ** into the WHERE clause, go through and verify that none of the terms
+ ** in the ON clauses reference tables to the right of the ON clause.
+ ** Do this now, after name resolution, but before query flattening
+ */
+ if( p->selFlags & SF_OnToWhere ){
+ selectCheckOnClauses(pParse, p);
+ if( pParse->nErr ){
+ goto select_end;
+ }
+ }
+
/* If the SF_UFSrcCheck flag is set, then this function is being called
** as part of populating the temp table for an UPDATE...FROM statement.
** In this case, it is an error if the target object (pSrc->a[0]) name
#define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */
#define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */
#define SF_Correlated 0x20000000 /* True if references the outer context */
+#define SF_OnToWhere 0x40000000 /* One or more ON clauses moved to WHERE */
/* True if SrcItem X is a subquery that has SF_NestedFrom */
#define IsNestedFrom(X) \
prereqAll |= x;
extraRight = x-1; /* ON clause terms may not be used with an index
** on left table of a LEFT JOIN. Ticket #3015 */
- if( (prereqAll>>1)>=x ){
- sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
- return;
- }
}else if( (prereqAll>>1)>=x ){
- /* The ON clause of an INNER JOIN references a table to its right.
- ** Most other SQL database engines raise an error. But SQLite versions
- ** 3.0 through 3.38 just put the ON clause constraint into the WHERE
- ** clause and carried on. Beginning with 3.39, raise an error only
- ** if there is a RIGHT or FULL JOIN in the query. This makes SQLite
- ** more like other systems, and also preserves legacy. */
- if( ALWAYS(pSrc->nSrc>0) && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
- sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
- return;
- }
ExprClearProperty(pExpr, EP_InnerON);
}
}