/ Check-in [3dd35f51]
Login

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

Overview
Comment:Increase the initial value of WhereLoopBuilder.iPlanLimit to 20K. Issue a warning if the iPlanLimit reaches zero.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 3dd35f51187574f47f860405309877cdbf9dc5710703dfd98cf98073b771140c
User & Date: drh 2018-09-24 10:47:33
Context
2018-09-24
12:37
Use compile-time options SQLITE_QUERY_PLANNER_LIMIT and SQLITE_QUERY_PLANNER_LIMIT_INCR to control the value for WhereLoopBuilder.iPlanLimit, rather than embedding magic numbers in the code. check-in: 903e5018 user: drh tags: trunk
10:47
Increase the initial value of WhereLoopBuilder.iPlanLimit to 20K. Issue a warning if the iPlanLimit reaches zero. check-in: 3dd35f51 user: drh tags: trunk
2018-09-23
02:01
Fix a faulty assert() in the validation logic for the LEFT JOIN strength reduction optimization. Problem found by OSSFuzz. check-in: 2fd62fcc user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to src/where.c.

3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
....
3575
3576
3577
3578
3579
3580
3581

3582
3583
3584
3585
3586
3587
3588

  /* Loop over the tables in the join, from left to right */
  pNew = pBuilder->pNew;
  whereLoopInit(pNew);
  /* Some pathological queries provide an unreasonable number of indexing
  ** options. The iPlanLimit value prevents these queries from taking up
  ** too much time in the planner. When iPlanLimit reaches zero, no further
  ** index+constraint options are considered. Seed iPlanLimit to 10K but
  ** also add an extra 1K to each table of the join, to ensure that each
  ** table at least gets 1K opportunities. */
  pBuilder->iPlanLimit = 10000;
  for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
    Bitmask mUnusable = 0;
    pNew->iTab = iTab;
    pBuilder->iPlanLimit += 1000;  /* 1000 bonus for each table in the join */
    pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
    if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
      /* This condition is true when pItem is the FROM clause term on the
................................................................................
    if( rc==SQLITE_OK && pBuilder->pWC->hasOr ){
      rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
    }
    mPrior |= pNew->maskSelf;
    if( rc || db->mallocFailed ){
      if( rc==SQLITE_DONE ){
        /* We hit the query planner search limit set by iPlanLimit */

        rc = SQLITE_OK;
      }else{
        break;
      }
    }
  }








|


|







 







>







3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
....
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589

  /* Loop over the tables in the join, from left to right */
  pNew = pBuilder->pNew;
  whereLoopInit(pNew);
  /* Some pathological queries provide an unreasonable number of indexing
  ** options. The iPlanLimit value prevents these queries from taking up
  ** too much time in the planner. When iPlanLimit reaches zero, no further
  ** index+constraint options are considered. Seed iPlanLimit to 20K but
  ** also add an extra 1K to each table of the join, to ensure that each
  ** table at least gets 1K opportunities. */
  pBuilder->iPlanLimit = 20000;
  for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
    Bitmask mUnusable = 0;
    pNew->iTab = iTab;
    pBuilder->iPlanLimit += 1000;  /* 1000 bonus for each table in the join */
    pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
    if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
      /* This condition is true when pItem is the FROM clause term on the
................................................................................
    if( rc==SQLITE_OK && pBuilder->pWC->hasOr ){
      rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
    }
    mPrior |= pNew->maskSelf;
    if( rc || db->mallocFailed ){
      if( rc==SQLITE_DONE ){
        /* We hit the query planner search limit set by iPlanLimit */
        sqlite3_log(SQLITE_WARNING, "abbreviated query algorithm search");
        rc = SQLITE_OK;
      }else{
        break;
      }
    }
  }