/ Check-in [5ef64b0f]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Simplify the fix in the previous commit.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 5ef64b0f55d952c7b0016055eaf6bbc1b5b7afc09a62ee8e5e694ffa9863ac7c
User & Date: dan 2019-09-20 21:12:40
Context
2019-09-21
13:34
Add --multithread, --serialized, and --singlethread options to the speed-check.sh test script. check-in: c17078af user: drh tags: trunk
2019-09-20
21:12
Simplify the fix in the previous commit. check-in: 5ef64b0f user: dan tags: trunk
20:52
Fix a problem with queries containing a min() or max() function for which the FILTER clause excludes all rows. check-in: b1d7e104 user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/select.c.

5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
....
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368



5369
5370
5371
5372
5373
5374
5375
....
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
** of setting and clearing regAcc.
*/
static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
  Vdbe *v = pParse->pVdbe;
  int i;
  int regHit = 0;
  int addrHitTest = 0;
  int bFilterMinMax = 0;
  struct AggInfo_func *pF;
  struct AggInfo_col *pC;

  pAggInfo->directMode = 1;
  for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
    int nArg;
    int addrNext = 0;
................................................................................
    assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
    assert( !IsWindowFunc(pF->pExpr) );
    if( ExprHasProperty(pF->pExpr, EP_WinFunc) ){
      Expr *pFilter = pF->pExpr->y.pWin->pFilter;
      if( pAggInfo->nAccumulator 
       && (pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) 
      ){
        bFilterMinMax = 1;
        if( regHit==0 ) regHit = ++pParse->nMem;
        /* If this is the first row of the group (regAcc==0), clear the
        ** "magnet" register regHit so that the accumulator registers
        ** are populated even if the FILTER clause causes control to
        ** skip over the invocation of min() or max() altogether */



        sqlite3VdbeAddOp2(v, OP_Copy, regAcc, regHit);
      }
      addrNext = sqlite3VdbeMakeLabel(pParse);
      sqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL);
    }
    if( pList ){
      nArg = pList->nExpr;
................................................................................
  }
  if( regHit ){
    addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v);
  }
  for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
    sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
  }
  if( bFilterMinMax ){
    /* If there is a min() or max() with a FILTER clause, then ensure that
    ** the "magnet" register is set to indicate "do not attract" after
    ** loading column values into the accumulator registers */
    sqlite3VdbeAddOp2(v, OP_Integer, 1, regHit);
  }

  pAggInfo->directMode = 0;
  if( addrHitTest ){
    sqlite3VdbeJumpHere(v, addrHitTest);
  }
}








<







 







<



|
|
>
>
>







 







<
<
<
<
<
<







5339
5340
5341
5342
5343
5344
5345

5346
5347
5348
5349
5350
5351
5352
....
5355
5356
5357
5358
5359
5360
5361

5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
....
5415
5416
5417
5418
5419
5420
5421






5422
5423
5424
5425
5426
5427
5428
** of setting and clearing regAcc.
*/
static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
  Vdbe *v = pParse->pVdbe;
  int i;
  int regHit = 0;
  int addrHitTest = 0;

  struct AggInfo_func *pF;
  struct AggInfo_col *pC;

  pAggInfo->directMode = 1;
  for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
    int nArg;
    int addrNext = 0;
................................................................................
    assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
    assert( !IsWindowFunc(pF->pExpr) );
    if( ExprHasProperty(pF->pExpr, EP_WinFunc) ){
      Expr *pFilter = pF->pExpr->y.pWin->pFilter;
      if( pAggInfo->nAccumulator 
       && (pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) 
      ){

        if( regHit==0 ) regHit = ++pParse->nMem;
        /* If this is the first row of the group (regAcc==0), clear the
        ** "magnet" register regHit so that the accumulator registers
        ** are populated if the FILTER clause jumps over the the 
        ** invocation of min() or max() altogether. Or, if this is not
        ** the first row (regAcc==1), set the magnet register so that the
        ** accumulators are not populated unless the min()/max() is invoked and
        ** indicates that they should be.  */
        sqlite3VdbeAddOp2(v, OP_Copy, regAcc, regHit);
      }
      addrNext = sqlite3VdbeMakeLabel(pParse);
      sqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL);
    }
    if( pList ){
      nArg = pList->nExpr;
................................................................................
  }
  if( regHit ){
    addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v);
  }
  for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
    sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
  }







  pAggInfo->directMode = 0;
  if( addrHitTest ){
    sqlite3VdbeJumpHere(v, addrHitTest);
  }
}