SQLite

Check-in [d6946f33c7]
Login

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

Overview
Comment:Minor fixes to the OR-clause processing in the NGQP.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | nextgen-query-plan-exp
Files: files | file ages | folders
SHA1: d6946f33c7851aa7efb04b93ac2ae1ac50c26eec
User & Date: drh 2013-05-11 00:06:23.252
Context
2013-05-14
15:31
First attempt to get ORDER BY optimization working in NGQP. (check-in: 9fe2029255 user: drh tags: nextgen-query-plan-exp)
2013-05-11
00:06
Minor fixes to the OR-clause processing in the NGQP. (check-in: d6946f33c7 user: drh tags: nextgen-query-plan-exp)
2013-05-10
20:26
Now generating OR-clause plans. (check-in: e17003fcfe user: drh tags: nextgen-query-plan-exp)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/where.c.
5333
5334
5335
5336
5337
5338
5339
5340

5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358

5359
5360
5361
5362
5363
5364
5365
    }
  }
  *pNew = savedLoop;
  return rc;
}

/*
** Add all WhereLoop objects for the iTab-th table of the join.  That

** table is guaranteed to be a b-tree table, not a virtual table.
*/
static int whereLoopAddBtree(
  WhereLoopBuilder *pBuilder, /* WHERE clause information */
  Bitmask mExtra              /* Extra prerequesites for using this table */
){
  Index *pProbe;              /* An index we are evaluating */
  Index sPk;                  /* A fake index object for the primary key */
  tRowcnt aiRowEstPk[2];      /* The aiRowEst[] value for the sPk index */
  int aiColumnPk = -1;        /* The aColumn[] value for the sPk index */
  struct SrcList_item *pSrc;  /* The FROM clause btree term to add */
  WhereLoop *pNew;            /* Template WhereLoop object */
  int rc = SQLITE_OK;         /* Return code */
  double rSize;               /* number of rows in the table */
  double rLogSize;            /* Logarithm of the number of rows in the table */

  pNew = pBuilder->pNew;
  pSrc = pBuilder->pTabList->a + pNew->iTab;


  if( pSrc->pIndex ){
    /* An INDEXED BY clause specifies a particular index to use */
    pProbe = pSrc->pIndex;
  }else{
    /* There is no INDEXED BY clause.  Create a fake Index object in local
    ** variable sPk to represent the rowid primary key index.  Make this







|
>
|

















>







5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
    }
  }
  *pNew = savedLoop;
  return rc;
}

/*
** Add all WhereLoop objects a single table of the join were the table
** is idenfied by pBuilder->pNew->iTab.  That table is guaranteed to be
** a b-tree table, not a virtual table.
*/
static int whereLoopAddBtree(
  WhereLoopBuilder *pBuilder, /* WHERE clause information */
  Bitmask mExtra              /* Extra prerequesites for using this table */
){
  Index *pProbe;              /* An index we are evaluating */
  Index sPk;                  /* A fake index object for the primary key */
  tRowcnt aiRowEstPk[2];      /* The aiRowEst[] value for the sPk index */
  int aiColumnPk = -1;        /* The aColumn[] value for the sPk index */
  struct SrcList_item *pSrc;  /* The FROM clause btree term to add */
  WhereLoop *pNew;            /* Template WhereLoop object */
  int rc = SQLITE_OK;         /* Return code */
  double rSize;               /* number of rows in the table */
  double rLogSize;            /* Logarithm of the number of rows in the table */

  pNew = pBuilder->pNew;
  pSrc = pBuilder->pTabList->a + pNew->iTab;
  assert( !IsVirtual(pSrc->pTab) );

  if( pSrc->pIndex ){
    /* An INDEXED BY clause specifies a particular index to use */
    pProbe = pSrc->pIndex;
  }else{
    /* There is no INDEXED BY clause.  Create a fake Index object in local
    ** variable sPk to represent the rowid primary key index.  Make this
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
    ** considered. */
    if( pSrc->pIndex ) break;
  }
  return rc;
}

/*
** Add all WhereLoop objects for the iTab-th table of the join.  That
** table is guaranteed to be a virtual table.
*/
static int whereLoopAddVirtual(
  WhereLoopBuilder *pBuilder,  /* WHERE clause information */
  Bitmask mExtra               /* Extra prerequesites for using this table */
){
  Parse *pParse;               /* The parsing context */
  WhereClause *pWC;            /* The WHERE clause */







|
|







5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
    ** considered. */
    if( pSrc->pIndex ) break;
  }
  return rc;
}

/*
** Add all WhereLoop objects for a table of the join identified by
** pBuilder->pNew->iTab.  That table is guaranteed to be a virtual table.
*/
static int whereLoopAddVirtual(
  WhereLoopBuilder *pBuilder,  /* WHERE clause information */
  Bitmask mExtra               /* Extra prerequesites for using this table */
){
  Parse *pParse;               /* The parsing context */
  WhereClause *pWC;            /* The WHERE clause */
5480
5481
5482
5483
5484
5485
5486

5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503

  pParse = pBuilder->pParse;
  db = pParse->db;
  pWC = pBuilder->pWC;
  pNew = pBuilder->pNew;
  pSrc = &pBuilder->pTabList->a[pNew->iTab];
  pTab = pSrc->pTab;

  pIdxInfo = allocateIndexInfo(pParse, pWC, pSrc, pBuilder->pOrderBy);
  if( pIdxInfo==0 ) return SQLITE_NOMEM;
  pNew->prereq = 0;
  pNew->rSetup = 0;
  pNew->wsFlags = WHERE_VIRTUALTABLE;
  pNew->nTerm = 0;
  pNew->u.vtab.needFree = 0;
  pUsage = pIdxInfo->aConstraintUsage;

  for(iPhase=0; iPhase<=2; iPhase++){
    if( !seenIn && (iPhase&1)!=0 ){
      iPhase++;
      if( iPhase>3 ) break;
    }
    if( !seenVar && iPhase>1 ) break;
    pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
    for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){







>









|







5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506

  pParse = pBuilder->pParse;
  db = pParse->db;
  pWC = pBuilder->pWC;
  pNew = pBuilder->pNew;
  pSrc = &pBuilder->pTabList->a[pNew->iTab];
  pTab = pSrc->pTab;
  assert( IsVirtual(pTab) );
  pIdxInfo = allocateIndexInfo(pParse, pWC, pSrc, pBuilder->pOrderBy);
  if( pIdxInfo==0 ) return SQLITE_NOMEM;
  pNew->prereq = 0;
  pNew->rSetup = 0;
  pNew->wsFlags = WHERE_VIRTUALTABLE;
  pNew->nTerm = 0;
  pNew->u.vtab.needFree = 0;
  pUsage = pIdxInfo->aConstraintUsage;

  for(iPhase=0; iPhase<=3; iPhase++){
    if( !seenIn && (iPhase&1)!=0 ){
      iPhase++;
      if( iPhase>3 ) break;
    }
    if( !seenVar && iPhase>1 ) break;
    pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
    for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545

5546
5547

5548
5549
5550
5551
5552
5553
5554
    pIdxInfo->orderByConsumed = 0;
    /* ((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;
    assert( pIdxInfo->nConstraint<=pBuilder->mxTerm );
    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
        ){
          rc = SQLITE_ERROR;







<
<

>


>







5539
5540
5541
5542
5543
5544
5545


5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
    pIdxInfo->orderByConsumed = 0;
    /* ((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;


    mxTerm = -1;
    for(i=0; i<pBuilder->mxTerm; i++) pNew->aTerm[i] = 0;
    for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
      if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
        if( iTerm>=pBuilder->mxTerm ) break;
        j = pIdxCons->iTermOffset;
        if( iTerm>=pIdxInfo->nConstraint
         || j<0
         || j>=pWC->nTerm
         || pNew->aTerm[iTerm]!=0
        ){
          rc = SQLITE_ERROR;