]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Do not allow table-function argument expressions on the RHS of an OUTER join to refer...
authordan <Dan Kennedy>
Mon, 9 Feb 2026 14:45:17 +0000 (14:45 +0000)
committerdan <Dan Kennedy>
Mon, 9 Feb 2026 14:45:17 +0000 (14:45 +0000)
FossilOrigin-Name: 021e48e28931afd781e76db6293e60fd2ffb8377cb1051e8b802f2743a10fa5d

manifest
manifest.uuid
src/select.c
test/tabfunc01.test

index 3a8bbb9bcd6d4c982f30ba17b19df7e0c6158c64..57aec2a3663cf27346c3b9e367a88d8013ff23d5 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\smethod\sname\stypo\sin\stest-only\scode\swhich\scould\shide\sthe\striggering\serror\scondition.
-D 2026-02-08T12:13:19.663
+C Do\snot\sallow\stable-function\sargument\sexpressions\son\sthe\sRHS\sof\san\sOUTER\sjoin\sto\srefer\sto\sFROM\sclause\selements\sto\stheir\sright.
+D 2026-02-09T14:45:17.973
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -738,7 +738,7 @@ F src/printf.c b1b29b5e58e1530d5daeee5963d3c318d8ab2d7e38437580e28755753e0c1ded
 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c 47aa7fdc9ec4c19b103ac5e79d7887d30119b5675309facf5eed1118391c868b
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
-F src/select.c af5f50443de19c071396f8c572e6b7e1f359a7e0a0f3c705a2ec10a151312380
+F src/select.c 3bbcb0dbdac61a856b1ba3e2ed64d609935eca884b20208e5df5eeb183e2413f
 F src/shell.c.in b944a21d98cc4c6107bfd1ec702440579cb4bf86435125b67ff661180e9453b5
 F src/sqlite.h.in 8bcbaecfe2cbecf8c5c1381354fcdd7d307443e88b4953fccb222456c1267b61
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
@@ -1698,7 +1698,7 @@ F test/sync.test a619e407ede58a7b6e3e44375328628559fc9695a9c24c47cb5690a866b0031
 F test/sync2.test 06152269ed73128782c450c355988fe8dd794d305833af75e1a5e79edd4dae47
 F test/syscall.test a067468b43b8cb2305e9f9fe414e5f40c875bb5d2cba5f00b8154396e95fcf37
 F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
-F test/tabfunc01.test 56eeae736217204bb1d9f9ef38340d48058f809b64249217cf77ff4ba600cc21
+F test/tabfunc01.test cfa96a9a235c39fb0cae69928b989b28bfec108f62d2533486f76e32dcedfdfb
 F test/table.test e87294bf1c80bfd7792142b84ab32ea5beb4f3f71e535d7fb263a6b2068377bf
 F test/tableapi.test e37c33e6be2276e3a96bb54b00eea7f321277115d10e5b30fdb52a112b432750
 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
@@ -2194,8 +2194,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P dcd22fd6d135892852358c8cfb5049dce4a1410dbc0f28cafc8b340f69350165
-R 91019b95f7ce9d20c628723596a0b345
-U stephan
-Z 836928478383cf3edbd8e931cf0778a9
+P b2c1a4184c3de5a26524906ba04ce6c9c80b27f8d89c40fde7bbc8f5a9f99e34
+R 384f0afa58672ad1fa5b23ebbc48f852
+U dan
+Z 071a436235897957c7442402e1c10272
 # Remove this line to create a well-formed Fossil manifest.
index 7751194d5d0ab706700320a16d244f1d36c8e4de..df960cec01abc2b6fbcde1b2bafba46e093b4ce8 100644 (file)
@@ -1 +1 @@
-b2c1a4184c3de5a26524906ba04ce6c9c80b27f8d89c40fde7bbc8f5a9f99e34
+021e48e28931afd781e76db6293e60fd2ffb8377cb1051e8b802f2743a10fa5d
index 1679c8772c5c3c2b424fb65adc495b2d5c4a6bd1..600ef021fce5e5a42c5330b21986ed1c9b1beb27 100644 (file)
@@ -659,6 +659,10 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){
       pRight->fg.isOn = 1;
       p->selFlags |= SF_OnToWhere;
     }
+
+    if( IsVirtual(pRightTab) && joinType==EP_OuterON && pRight->u1.pFuncArg ){
+      p->selFlags |= SF_OnToWhere;
+    }
   }
   return 0;
 }
@@ -7398,6 +7402,7 @@ typedef struct CheckOnCtx CheckOnCtx;
 struct CheckOnCtx {
   SrcList *pSrc;                  /* SrcList for this context */
   int iJoin;                      /* Cursor numbers must be =< than this */
+  int bFuncArg;                   /* True for table-function arg */
   CheckOnCtx *pParent;            /* Parent context */
 };
 
@@ -7449,7 +7454,9 @@ static int selectCheckOnClausesExpr(Walker *pWalker, Expr *pExpr){
       if( iTab>=pSrc->a[0].iCursor && iTab<=pSrc->a[pSrc->nSrc-1].iCursor ){
         if( pCtx->iJoin && iTab>pCtx->iJoin ){
           sqlite3ErrorMsg(pWalker->pParse, 
-              "ON clause references tables to its right");
+              "%s references tables to its right",
+              (pCtx->bFuncArg ? "table-function argument" : "ON clause")
+          );
           return WRC_Abort;
         }
         break;
@@ -7487,6 +7494,7 @@ static int selectCheckOnClausesSelect(Walker *pWalker, Select *pSelect){
 static void selectCheckOnClauses(Parse *pParse, Select *pSelect){
   Walker w;
   CheckOnCtx sCtx;
+  int ii;
   assert( pSelect->selFlags & SF_OnToWhere );
   assert( pSelect->pSrc!=0 && pSelect->pSrc->nSrc>=2 );
   memset(&w, 0, sizeof(w));
@@ -7496,8 +7504,22 @@ static void selectCheckOnClauses(Parse *pParse, Select *pSelect){
   w.u.pCheckOnCtx = &sCtx;
   memset(&sCtx, 0, sizeof(sCtx));
   sCtx.pSrc = pSelect->pSrc;
-  sqlite3WalkExprNN(&w, pSelect->pWhere);
+  sqlite3WalkExpr(&w, pSelect->pWhere);
   pSelect->selFlags &= ~SF_OnToWhere;
+
+  /* Check for any table-function args that are attached to virtual tables 
+  ** on the RHS of an outer join. They are subject to the same constraints
+  ** as ON clauses. */
+  sCtx.bFuncArg = 1;
+  for(ii=0; ii<pSelect->pSrc->nSrc; ii++){
+    SrcItem *pItem = &pSelect->pSrc->a[ii];
+    if( pItem->fg.isTabFunc
+     && (pItem->fg.jointype & JT_OUTER)
+    ){
+      sCtx.iJoin = pItem->iCursor;
+      sqlite3WalkExprList(&w, pItem->u1.pFuncArg);
+    }
+  }
 }
 
 /*
index 9a2017c46a7cdfde97197c954d53b62fd927b354..60f546ce42a7d409984bcd702ff1f947693a2016 100644 (file)
@@ -668,6 +668,20 @@ do_execsql_test 1370 {
   SELECT * FROM generate_series(0,0,0);
 } {}
 
+reset_db
+load_static_extension db series
+do_execsql_test 1400 {
+  CREATE TABLE t1(x);
+  CREATE TABLE t2(y);
+}
+do_catchsql_test 1410 {
+  SELECT x, y, value
+  FROM (t1 RIGHT JOIN generate_series(t2.y,5) AS value) JOIN t2;
+} {1 {table-function argument references tables to its right}}
+do_catchsql_test 1420 {
+  SELECT x, y, value 
+  FROM t2 JOIN (t1 RIGHT JOIN generate_series(t2.y,5) AS value) 
+} {1 {no such column: t2.y}}
 
 
 # Free up memory allocations