From 34615b9c1f2fa513e02911bed20fe0579a9c51cb Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 29 Sep 2026 11:52:00 +0000 Subject: [PATCH] Reset the nullRow flag on the pseudo-cursor on each iteration of the loop when the RHS of a LEFT JOIN is a multi-row VALUES clause. Fix for [bugs:/info/2026-09-29T00:41:09Z|Bug 2026-09-29T00:41:09Z]. Problem introduced by check-in [a120c9235f125e05] with a missed opportunity to fix the problem at check-in [8c0f69e0e4ae0a44]. FossilOrigin-Name: 8e59d3c0a428ff12ea852c7a9f15b6b7b4ca0da55708f3d303b2e88818a17476 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 9 ++++++--- src/wherecode.c | 3 +++ test/values.test | 12 ++++++++++++ 5 files changed, 30 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index c96bb8bd9a..a09f84f9e2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sduplicate\stest\scase\sidentifier\slabel\sin\sspeedtest1.c. -D 2026-09-28T16:30:59.230 +C Reset\sthe\snullRow\sflag\son\sthe\spseudo-cursor\son\seach\siteration\sof\sthe\sloop\nwhen\sthe\sRHS\sof\sa\sLEFT\sJOIN\sis\sa\smulti-row\sVALUES\sclause.\s\sFix\sfor\n[bugs:/info/2026-09-29T00:41:09Z|Bug\s2026-09-29T00:41:09Z].\s\sProblem\nintroduced\sby\scheck-in\s[a120c9235f125e05]\swith\sa\smissed\sopportunity\sto\nfix\sthe\sproblem\sat\scheck-in\s[8c0f69e0e4ae0a44]. +D 2026-09-29T11:52:00.808 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -810,7 +810,7 @@ F src/upsert.c dd9f0fcccbfb4f20e1026a21a7254ba3f2c08e9cfa92affaff5b5ec3b00ea549 F src/utf.c c5bec56770b71fe75e12f1f7b0a512032e1fd3d1f83c50c4ab4474ced20347a4 F src/util.c 4437408e09cef6dbb63a8b8ba28be53bdc098ec890e5e64ad7ae1fc83448962e F src/vacuum.c d3d35d8ae893d419ade5fa196d761a83bddcbb62137a1a157ae751ef38b26e82 -F src/vdbe.c 076f4de32c507a713cb2d666d6bc6836c3b5637fec1159d2ef39328f73989377 +F src/vdbe.c 134147162547f7d02e96aad416c7922185a47e4568327cbf773cc7de313c4310 F src/vdbe.h b6ffb28da04363fd5d439b8204118fd3f2e751abe4f8e3edb089155fb90d4607 F src/vdbeInt.h 68e5ab63f184f2871780c83ce78b425d0360869611baea4c65575f91f76ac1d3 F src/vdbeapi.c 5f5f86d4642ce1927b4b45a6b87a978ef6b11c8420e6ce440695177618fc25d0 @@ -827,7 +827,7 @@ F src/wal.h c6251cfc1950643a976625ca452e46dc9b466b4f5dd2e85f244f29f79bf68ace F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/where.c 717331794a92c00151b080c2c44de592720d26d03ea50de34e3fab05ab09ba61 F src/whereInt.h f039ad303bc2913de673e431821ef8db3b619d249e6e5548d90072a684e72285 -F src/wherecode.c 1c4e9adfdb24228c1b3fbd06b4a84000fcfbc5519e828f212e6704a0b7189119 +F src/wherecode.c 1a6d2999159b28d8c0b968458b90ec183b3813cb332c11515ab60a73db5c07fd F src/whereexpr.c 76f72a95c5cf0e8a8edb679ca4fb7afa17ba45ff4effe73c414266510109e701 F src/window.c 566d0f2e9cc843f5cd5b22c861862ef4d10f6040ddf6b13c97bf39950ec2fc2a F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1969,7 +1969,7 @@ F test/vacuum4.test 7ea76b769fffeb41f925303b04cbcf5a5bbeabe55e4c60ae754ff24eeeb7 F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2f48c F test/vacuum6.test b137b04bf3392d3f5c3b8fda0ce85a6775a70ca112f6559f74ff52dc9ce042fd F test/vacuummem.test 4b30f5b95a9ff86e9d5c20741e50a898b2dc10b0962a3211571eb165357003fb -F test/values.test 45d78da364a5739de5c7b36de64fe41040d7df56dcd399374728c5380de1535e +F test/values.test 9fb17305b7089d1f4181874c74872d3dddc4bc5893c02b1177ca49641faa2e3d F test/valuesfault.test 2ef23ed965e3bd08e268cdc38a0d11653390ddbbe1e8e2e98d16f55edd30f6e8 F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 @@ -2221,8 +2221,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P 03bb7acfe8af5dc22af698a73343cc5c003df2d57f321e3c1818826238e046b1 -R 22eb5b2ed189cc14410a469f7fdd43ba +P 6f7db1d7313892260298aa78cfa1a3d91e5e55aebd16862d77835c5e070857c5 +R 624ffc8614f935e88a9695baf0e36037 U drh -Z 4f8836648e8a8472e2822bf057a28fcb +Z f085249638ded4bccfda962b807f2b0a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e2a930d70f..ca89fe767a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6f7db1d7313892260298aa78cfa1a3d91e5e55aebd16862d77835c5e070857c5 +8e59d3c0a428ff12ea852c7a9f15b6b7b4ca0da55708f3d303b2e88818a17476 diff --git a/src/vdbe.c b/src/vdbe.c index 8ac2b5d64e..f7358a6cb5 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6347,14 +6347,17 @@ case OP_Rowid: { /* out2, ncycle */ break; } -/* Opcode: NullRow P1 * * * * +/* Opcode: NullRow P1 P2 * * * ** -** Move the cursor P1 to a null row. Any OP_Column operations +** Move the cursor P1 to a null row if P2 is 0. Any OP_Column operations ** that occur while the cursor is on the null row will always ** write a NULL. ** ** If cursor P1 is not previously opened, open it now to a special ** pseudo-cursor that always returns NULL for every column. +** +** If P2 is not 0, then the nullRow flag on the pseudo-cursor is +** turned off. */ case OP_NullRow: { VdbeCursor *pC; @@ -6371,7 +6374,7 @@ case OP_NullRow: { pC->noReuse = 1; pC->uc.pCursor = sqlite3BtreeFakeValidCursor(); } - pC->nullRow = 1; + pC->nullRow = (pOp->p2==0); pC->cacheStatus = CACHE_STALE; if( pC->eCurType==CURTYPE_BTREE ){ assert( pC->uc.pCursor!=0 ); diff --git a/src/wherecode.c b/src/wherecode.c index ae0cf8fa8f..995ebeca47 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1595,6 +1595,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( pLevel->iLeftJoin = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); VdbeComment((v, "init LEFT JOIN match flag")); + if( pTabItem->fg.viaCoroutine ){ + sqlite3VdbeAddOp2(v, OP_NullRow, pTabItem->iCursor, 1); + } } /* Special case of a FROM clause subquery implemented as a co-routine */ diff --git a/test/values.test b/test/values.test index 1025442b39..240013e19c 100644 --- a/test/values.test +++ b/test/values.test @@ -766,5 +766,17 @@ do_execsql_test 20.9 { VALUES(10),(CASE 4.2 WHEN 239 IS TRUE THEN 3.7 WHEN 554 THEN 275 ELSE 16 END); } {10 16} +# Bug 2026-09-29T00:41:09Z +# +reset_db +db null NULL +do_execsql_test 21.1 { + CREATE TABLE t3(id INT); + INSERT INTO t3 VALUES (0), (3), (0), (5); + SELECT t3.id, x.c0 + FROM t3 LEFT JOIN (SELECT 1 AS c0 FROM (VALUES(0),(4))) AS x + ON t3.id>=1; +} {0 NULL 3 1 3 1 0 NULL 5 1 5 1} + finish_test