-C Attempt\sto\sdetect\serrors\scause\sby\sON\sclauses\sthat\srefer\sto\stables\sto\sthe\sright\sof\sthemselves\swhile\sresolving\snames,\sinstead\sof\slater\son\safter\squery-flattening\sand\sother\soperations\shave\scomplicated\sthings.
-D 2025-08-22T16:25:34.129
+C Improve\sperformance\sof\sthis\spatch.
+D 2025-08-22T19:14:35.864
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F src/prepare.c 2af0b5c1ec787c8eebd21baa9d79caf4a4dc3a18e76ce2edbf2027d706bca37a
F src/printf.c 5f0c957af9699e849d786e8fbaa3baab648ca5612230dc17916434c14bc8698f
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
-F src/resolve.c f400b2c1fa22ffe779901fba13deace5e483e2724addebaa9242dd1cedc8a56b
+F src/resolve.c 0d0b8146eb85c7a4cda2f81bc863f29e6ce3fa2d5651f7a5e77f3cdcce0c0f0e
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 78ebf432355e820962a5001277cb43ffe3d82441c6dc9c8f0aeb0b15fbd5dd02
F src/shell.c.in 0636915df0dbac6c780f04959f5d1055f206fb281b2c8fc8b113fe7bfc7d44ef
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 9ada44eb6d26532e45cdd2ed8d5707f1734d0177a13b493ff9cf070e0a992522
-R 6308fbfdbe1bb96ade6fc59905bcaa05
-T *branch * on-clause-error-fix
-T *sym-on-clause-error-fix *
-T -sym-trunk *
+P 4bb527d3377f9e0e328c5e9901e5e6d45a90958004db5ff7000baa2ecb3ffeb6
+R aa93e87aea2d39245eaaa1ac42e84a48
U dan
-Z 5f576e89fa32a605a15ca63be19fcc55
+Z 6e9f35e4c1e718286f5d03be03b6a9af
# Remove this line to create a well-formed Fossil manifest.
/* Advance to the next name context. The loop will exit when either
** we have a match (cnt>0) or when we run out of name contexts.
*/
- if( cnt ){
- if( pNC->pOn && cnt==1 && pNC->pOn->w.iJoin<pExpr->iTable ){
- sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
- }
- break;
- }
+ if( cnt ) break;
pNC = pNC->pNext;
nSubquery++;
}while( pNC );
pNC->pOn = 0;
}else{
res = resolveExprStep(pWalker, pExpr);
+ if( pExpr->op==TK_COLUMN && pWalker->pParse->nErr==0 ){
+ /* A reference to a table column has just been resolved. Find the
+ ** name-context that it matched against: */
+ int iTab = pExpr->iTable;
+ do {
+ SrcList *p = pNC->pSrcList;
+ if( iTab>=p->a[0].iCursor && iTab<=p->a[p->nSrc-1].iCursor ) break;
+ pNC = pNC->pNext;
+ }while( pNC );
+
+ /* If the name-context that was matched against is currently inside
+ ** an ON expression, check that the specific FROM object within the
+ ** name-context was not to the right of the ON clause. If it was,
+ ** it is an error. */
+ if( pNC && pNC->pOn && pNC->pOn->w.iJoin<pExpr->iTable ){
+ sqlite3ErrorMsg(
+ pWalker->pParse, "ON clause references tables to its right"
+ );
+ }
+ }
}
return res;
/* Recursively resolve names in all subqueries in the FROM clause
*/
- if( pOuterNC ) pOuterNC->nNestedSelect++;
+ if( pOuterNC ){
+ pOuterNC->nNestedSelect++;
+ if( pOuterNC->pOn ){
+ sNC.ncFlags |= NC_On;
+ }
+ }
for(i=0; i<p->pSrc->nSrc; i++){
SrcItem *pItem = &p->pSrc->a[i];
assert( pItem->zName!=0
savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg);
pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg);
w.pParse = pNC->pParse;
- if( (pNC->ncFlags & (NC_On|NC_Where))==(NC_On|NC_Where) ){
- w.xExprCallback = resolveOnStep;
- }else{
- w.xExprCallback = resolveExprStep;
- }
+ w.xExprCallback = (pNC->ncFlags & NC_On) ? resolveOnStep : resolveExprStep;
w.xSelectCallback = (pNC->ncFlags & NC_NoSelect) ? 0 : resolveSelectStep;
w.xSelectCallback2 = 0;
w.u.pNC = pNC;
Walker w;
if( pList==0 ) return SQLITE_OK;
w.pParse = pNC->pParse;
- w.xExprCallback = resolveExprStep;
+ w.xExprCallback = (pNC->ncFlags & NC_On) ? resolveOnStep : resolveExprStep;
w.xSelectCallback = resolveSelectStep;
w.xSelectCallback2 = 0;
w.u.pNC = pNC;
Walker w;
assert( p!=0 );
- w.xExprCallback = resolveExprStep;
+ w.xExprCallback = 0;
w.xSelectCallback = resolveSelectStep;
w.xSelectCallback2 = 0;
w.pParse = pParse;