SQLite

Check-in [3c2e83a4a2]
Login

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

Overview
Comment:Fix memory leaks in the NGQP logic for virtual tables.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | nextgen-query-plan-exp
Files: files | file ages | folders
SHA1: 3c2e83a4a2c5e85202162feeb37ef7a3911c05a3
User & Date: drh 2013-05-08 20:05:58.332
Context
2013-05-10
02:00
Free up bits of wsFlags for reuse. Install the ORDER BY optimization infrastructure for the NGQP. (check-in: 82d50e1980 user: drh tags: nextgen-query-plan-exp)
2013-05-08
20:05
Fix memory leaks in the NGQP logic for virtual tables. (check-in: 3c2e83a4a2 user: drh tags: nextgen-query-plan-exp)
14:14
NGQP working with virtual tables, though many legacy tests fail and there are yet some memory leaks. (check-in: bd9327a968 user: drh tags: nextgen-query-plan-exp)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/where.c.
5438
5439
5440
5441
5442
5443
5444
5445
5446



5447
5448
5449
5450
5451
5452
5453
  pWC = pBuilder->pWC;
  pSrc = &pBuilder->pTabList->a[iTab];
  pTab = pSrc->pTab;
  pNew = pBuilder->pNew;
  pIdxInfo = allocateIndexInfo(pParse,pWC,pSrc,pBuilder->pOrderBy);
  if( pIdxInfo==0 ) return SQLITE_NOMEM;
  paTerm = sqlite3DbRealloc(db, pNew->aTerm,
                            pIdxInfo->nConstraint*sizeof(pNew->aTerm[0]));
  if( paTerm==0 ) return SQLITE_NOMEM;



  pNew->aTerm = paTerm;
  pNew->prereq = 0;
  pNew->iTab = iTab;
  pNew->maskSelf = getMask(pBuilder->pWC->pMaskSet, pSrc->iCursor);
  pNew->iOb = 0;
  pNew->nOb = 0;
  pNew->rSetup = 0;







|
|
>
>
>







5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
  pWC = pBuilder->pWC;
  pSrc = &pBuilder->pTabList->a[iTab];
  pTab = pSrc->pTab;
  pNew = pBuilder->pNew;
  pIdxInfo = allocateIndexInfo(pParse,pWC,pSrc,pBuilder->pOrderBy);
  if( pIdxInfo==0 ) return SQLITE_NOMEM;
  paTerm = sqlite3DbRealloc(db, pNew->aTerm,
                            (pIdxInfo->nConstraint+1)*sizeof(pNew->aTerm[0]));
  if( paTerm==0 ){
    sqlite3DbFree(db, pIdxInfo);
    return SQLITE_NOMEM;
  }
  pNew->aTerm = paTerm;
  pNew->prereq = 0;
  pNew->iTab = iTab;
  pNew->maskSelf = getMask(pBuilder->pWC->pMaskSet, pSrc->iCursor);
  pNew->iOb = 0;
  pNew->nOb = 0;
  pNew->rSetup = 0;
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
    /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
    pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
    rc = vtabBestIndex(pParse, pTab, pIdxInfo);
    if( rc ) goto whereLoopAddVtab_exit;
    pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
    pNew->prereq = 0;
    for(i=0; i<pIdxInfo->nConstraint; i++) pNew->aTerm[i] = 0;
    mxTerm = 0;
    for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
      if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
        j = pIdxCons->iTermOffset;
        if( iTerm>=pIdxInfo->nConstraint
         || j<0
         || j>=pWC->nTerm
         || pNew->aTerm[iTerm]!=0







|







5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
    /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
    pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
    rc = vtabBestIndex(pParse, pTab, pIdxInfo);
    if( rc ) goto whereLoopAddVtab_exit;
    pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
    pNew->prereq = 0;
    for(i=0; i<pIdxInfo->nConstraint; i++) pNew->aTerm[i] = 0;
    mxTerm = -1;
    for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
      if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
        j = pIdxCons->iTermOffset;
        if( iTerm>=pIdxInfo->nConstraint
         || j<0
         || j>=pWC->nTerm
         || pNew->aTerm[iTerm]!=0
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
        maskNew = pFrom->maskLoop | pWLoop->maskSelf;
        for(jj=0, pTo=aTo; jj<nTo && pTo->maskLoop!=maskNew; jj++){}
        if( jj>=nTo ){
          if( nTo>=mxChoice && rCost>=mxCost ) continue;
          if( nTo<mxChoice ){
            jj = nTo++;
          }else{
            for(jj=nTo-1; aTo[jj].rCost>=mxCost; jj--){ assert(jj>0); }
          }
          pTo = &aTo[jj];
        }else{
          if( pTo->rCost<=rCost ) continue;
        }
        pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf;
        pTo->nRow = pFrom->nRow * pWLoop->nOut;







|







5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
        maskNew = pFrom->maskLoop | pWLoop->maskSelf;
        for(jj=0, pTo=aTo; jj<nTo && pTo->maskLoop!=maskNew; jj++){}
        if( jj>=nTo ){
          if( nTo>=mxChoice && rCost>=mxCost ) continue;
          if( nTo<mxChoice ){
            jj = nTo++;
          }else{
            for(jj=nTo-1; aTo[jj].rCost<mxCost; jj--){ assert(jj>0); }
          }
          pTo = &aTo[jj];
        }else{
          if( pTo->rCost<=rCost ) continue;
        }
        pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf;
        pTo->nRow = pFrom->nRow * pWLoop->nOut;
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
    pFrom = aTo;
    aTo = aFrom;
    aFrom = pFrom;
    nFrom = nTo;
  }

  /* TEMPORARY */
//  if( nFrom==0 ){ sqlite3DbFree(db, pSpace); return SQLITE_ERROR; }
  assert( nFrom>0 );
  
  /* Find the lowest cost path and load it into pWInfo->a[].pWLoop */
  pFrom = aFrom;
  for(ii=1; ii<nFrom; ii++){
    if( pFrom->rCost>aFrom[ii].rCost ) pFrom = &aFrom[ii];
  }







|







5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
    pFrom = aTo;
    aTo = aFrom;
    aFrom = pFrom;
    nFrom = nTo;
  }

  /* TEMPORARY */
  if( nFrom==0 ){ sqlite3DbFree(db, pSpace); return SQLITE_ERROR; }
  assert( nFrom>0 );
  
  /* Find the lowest cost path and load it into pWInfo->a[].pWLoop */
  pFrom = aFrom;
  for(ii=1; ii<nFrom; ii++){
    if( pFrom->rCost>aFrom[ii].rCost ) pFrom = &aFrom[ii];
  }