From ddd7421c9170317294e69a4287deda996a3cd3dc Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 2 Aug 2019 18:43:59 +0000 Subject: If a query like "SELECT min(a), b FROM t1" visits no rows where "a" is not null, extract a value for "b" from one of the rows where "a" is null. Possible fix for ticket [41866dc37]. FossilOrigin-Name: a7277ed0623dccdbf775ae6127611d6bc6e150f6942a048ab4281e5136c0e98d --- src/wherecode.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src') diff --git a/src/wherecode.c b/src/wherecode.c index a62544845..6152f7c35 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1694,6 +1694,25 @@ Bitmask sqlite3WhereCodeOneLoopStart( VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT ); + + if( bSeekPastNull && (pLoop->wsFlags & WHERE_TOP_LIMIT)==0 ){ + /* If bSeekPastNull is set only to skip past the NULL values for + ** a query like "SELECT min(a), b FROM t1", then add code so that + ** if there are no rows with (a IS NOT NULL), then do the seek + ** without jumping past NULLs instead. This allows the code in + ** select.c to pick a value for "b" in the above query. */ + assert( startEq==0 && (op==OP_SeekGT || op==OP_SeekLT) ); + assert( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0 && pWInfo->nOBSat>0 ); + sqlite3VdbeChangeP2(v, -1, sqlite3VdbeCurrentAddr(v)+1); + sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); + + op = aStartOp[(start_constraints<<2) + (1<<1) + bRev]; + assert( op!=0 ); + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); + VdbeCoverage(v); + VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); + VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); + } } /* Load the value for the inequality constraint at the end of the -- cgit v1.2.3