SQLite4
Check-in [c748d90f94]
Not logged in

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

Overview
SHA1 Hash:c748d90f94bcb61eed010927ae47c039dd3eb956
Date: 2013-07-30 11:55:56
User: dan
Comment:Reenable fts5 hooks in where.c.
Tags And Properties
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbe.c

2868
2869
2870
2871
2872
2873
2874
2875
2876

2877
2878
2879
2880
2881
2882
2883
    );
    nVarint = sqlite4VarintLen(pPk->iRoot);
    rc = sqlite4_buffer_resize(&pPk->sSeekKey, nVarint + nKey - nShort);
    if( rc!=SQLITE4_OK ) break;
    putVarint32((u8 *)(pPk->sSeekKey.p), pPk->iRoot);
    memcpy(((u8*)pPk->sSeekKey.p) + nVarint, &aKey[nShort], nKey-nShort);
    assert( pPk->sSeekKey.n>0 );
    pPk->rowChnged = 1;
  }


  break;
}

/* Opcode: SeekGe P1 P2 P3 P4 *
**
** P1 identifies an open database cursor. The cursor is repositioned so







<

>







2868
2869
2870
2871
2872
2873
2874

2875
2876
2877
2878
2879
2880
2881
2882
2883
    );
    nVarint = sqlite4VarintLen(pPk->iRoot);
    rc = sqlite4_buffer_resize(&pPk->sSeekKey, nVarint + nKey - nShort);
    if( rc!=SQLITE4_OK ) break;
    putVarint32((u8 *)(pPk->sSeekKey.p), pPk->iRoot);
    memcpy(((u8*)pPk->sSeekKey.p) + nVarint, &aKey[nShort], nKey-nShort);
    assert( pPk->sSeekKey.n>0 );

  }
  pPk->rowChnged = 1;

  break;
}

/* Opcode: SeekGe P1 P2 P3 P4 *
**
** P1 identifies an open database cursor. The cursor is repositioned so

Changes to src/where.c

3288
3289
3290
3291
3292
3293
3294
























3295
3296
3297
3298
3299
3300
3301
....
3362
3363
3364
3365
3366
3367
3368























3369
3370
3371
3372
3373
3374
3375
....
4502
4503
4504
4505
4506
4507
4508



























4509
4510
4511
4512
4513
4514
4515
....
4541
4542
4543
4544
4545
4546
4547




4548
4549
4550
4551
4552
4553
4554
....
5098
5099
5100
5101
5102
5103
5104
5105



5106
5107
5108
5109
5110
5111
5112
....
5976
5977
5978
5979
5980
5981
5982
5983


5984
5985
5986
5987
5988
5989
5990
5991
5992

5993
5994
5995
5996
5997
5998
5999
....
6148
6149
6150
6151
6152
6153
6154


















6155
6156
6157
6158
6159
6160
6161
6162
    sqlite4VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
  }
}
#else
# define explainOneScan(u,v,w,x,y,z)
#endif /* SQLITE4_OMIT_EXPLAIN */


























/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
*/
static Bitmask codeOneLoopStart(
  WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
................................................................................
    sqlite4VdbeAddOp2(v, OP_Integer, pTabItem->addrFillSub-1, regYield);
    pLevel->p2 =  sqlite4VdbeAddOp1(v, OP_Yield, regYield);
    VdbeComment((v, "next row of co-routine %s", pTabItem->pTab->zName));
    sqlite4VdbeAddOp2(v, OP_If, regYield+1, addrBrk);
    pLevel->op = OP_Goto;
  }else
#endif
























#ifndef SQLITE4_OMIT_VIRTUALTABLE
  if(  (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
    /* Case 1:  The table is a virtual-table.  Use the VFilter and VNext
    **          to access the data.
    */
    int iReg;   /* P3 Value for OP_VFilter */
................................................................................
      testcase( x==BMS-2 );
      if( x<BMS-1 ) m |= MASKBIT(x);
    }
  }
  return m;
}





























/*
** Add all WhereLoop objects for a single table of the join where 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(
................................................................................
  }else if( pSrc->notIndexed ){
    /* A NOT INDEXED clause means use the PK index */
    pProbe = pPk;
  }else{
    /* Otherwise, consider all indexes */
    pProbe = pSrc->pTab->pIndex;
  }





  rSize = whereCost(pSrc->pTab->nRowEst);
  rLogSize = estLog(rSize);

#ifndef SQLITE4_OMIT_AUTOMATIC_INDEX
  /* Automatic indexes */
  if( !pBuilder->pOrSet
................................................................................
        if( sqlite4_stricmp(z1, z2)!=0 ) continue;
      }
      obSat |= MASKBIT(i);
    }

    if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){
      Index *pPk = 0;
      if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){



        return 0;
      }else{
        isOrderDistinct = pIndex->onError!=OE_None;
        pPk = sqlite4FindPrimaryKey(pIndex->pTable, 0);
        nColumn = idxColumnCount(pIndex, pPk);
      }

................................................................................
      constructAutomaticIndex(pParse, &pWInfo->sWC, pTabItem, notReady, pLevel);
    }else
#endif
    if( pLoop->wsFlags & WHERE_INDEXED ){
      Index *pIx = pLoop->u.btree.pIndex;
      if( pIx->eIndexType==SQLITE4_INDEX_PRIMARYKEY ){
        pLevel->iIdxCur = pTabItem->iCursor;
      }


      else if( pIx->eIndexType!=SQLITE4_INDEX_FTS5 ){
        KeyInfo *pKey = sqlite4IndexKeyinfo(pParse, pIx);
        /* FIXME:  As an optimization use pTabItem->iCursor if WHERE_IDX_ONLY */
        int iIndexCur = pLevel->iIdxCur = iIdxCur ? iIdxCur : pParse->nTab++;
        assert( pIx->pSchema==pTab->pSchema );
        assert( iIndexCur>=0 );
        sqlite4VdbeAddOp4(v, OP_OpenRead, iIndexCur, pIx->tnum, iDb,
            (char*)pKey, P4_KEYINFO_HANDOFF);
        VdbeComment((v, "%s", pIx->zName));

      }
    }
    sqlite4CodeVerifySchema(pParse, iDb);
    notReady &= ~getMask(&pWInfo->sMaskSet, pTabItem->iCursor);
  }
  pWInfo->iTop = sqlite4VdbeCurrentAddr(v);
  if( db->mallocFailed ) goto whereBeginError;
................................................................................
          Index *pPk = sqlite4FindPrimaryKey(pTab, 0);
          pOp->p3 = pPk->tnum;
          pOp->p1 = pLevel->iIdxCur;
          pOp->opcode = OP_IdxRowkey;
        }
      }
    }


















  }

  /* Final cleanup
  */
  pParse->nQueryLoop = pWInfo->savedNQueryLoop;
  whereInfoFree(db, pWInfo);
  return;
}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>







 







|
>
>
>







 







|
>
>
|
|
<
<
|
|
|
|
|
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
....
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
....
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
....
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
....
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
....
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068


6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
....
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
    sqlite4VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
  }
}
#else
# define explainOneScan(u,v,w,x,y,z)
#endif /* SQLITE4_OMIT_EXPLAIN */


/*
** Try to find a MATCH expression that constrains the pTabItem table in the
** WHERE clause. If one exists, set *piTerm to the index in the pWC->a[] array
** and return non-zero. If no such expression exists, return 0.
*/
static int findMatchExpr(
  WhereClause *pWC, 
  SrcListItem *pTabItem, 
  int *piTerm
){
  int i;
  int iCsr = pTabItem->iCursor;

  for(i=0; i<pWC->nTerm; i++){
    Expr *pMatch = pWC->a[i].pExpr;
    if( pMatch->iTable==iCsr && pMatch->op==TK_MATCH ) break;
  }
  if( i==pWC->nTerm ) return 0;

  *piTerm = i;
  return 1;
}


/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
*/
static Bitmask codeOneLoopStart(
  WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
................................................................................
    sqlite4VdbeAddOp2(v, OP_Integer, pTabItem->addrFillSub-1, regYield);
    pLevel->p2 =  sqlite4VdbeAddOp1(v, OP_Yield, regYield);
    VdbeComment((v, "next row of co-routine %s", pTabItem->pTab->zName));
    sqlite4VdbeAddOp2(v, OP_If, regYield+1, addrBrk);
    pLevel->op = OP_Goto;
  }else
#endif

  if( (pLoop->wsFlags & WHERE_INDEXED)
   && (pLoop->u.btree.pIndex->eIndexType==SQLITE4_INDEX_FTS5)
  ){
    /* Case -1:  An FTS query */
    int iTerm;
    int rMatch;
    int rFree;
    findMatchExpr(pWC, pTabItem, &iTerm);

    rMatch = sqlite4ExprCodeTemp(pParse, pWC->a[iTerm].pExpr->pRight, &rFree);
    pWC->a[iTerm].wtFlags |= TERM_CODED;
    sqlite4Fts5CodeQuery(pParse, 
        pLoop->u.btree.pIndex, pLevel->iIdxCur, addrBrk, rMatch
    );
    sqlite4VdbeChangeP5(v, bRev);
    sqlite4ReleaseTempReg(pParse, rFree);

    pLevel->p2 = sqlite4VdbeCurrentAddr(v);
    sqlite4VdbeAddOp3(v, OP_SeekPk, iCur, 0, pLevel->iIdxCur);
    pLevel->op = OP_FtsNext;
    pLevel->p1 = pLevel->iIdxCur;
  }else

#ifndef SQLITE4_OMIT_VIRTUALTABLE
  if(  (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
    /* Case 1:  The table is a virtual-table.  Use the VFilter and VNext
    **          to access the data.
    */
    int iReg;   /* P3 Value for OP_VFilter */
................................................................................
      testcase( x==BMS-2 );
      if( x<BMS-1 ) m |= MASKBIT(x);
    }
  }
  return m;
}

static int whereLoopAddMatch(
  WhereLoopBuilder *pBuilder, 
  struct SrcListItem *pSrc,
  Bitmask mExtra, 
  int *pbDone
){
  WhereClause *pWC = pBuilder->pWC;
  int iTerm;
  int rc = SQLITE4_OK;
  if( findMatchExpr(pWC, pSrc, &iTerm) ){
    WhereLoop *pNew = pBuilder->pNew;

    pNew->prereq = pWC->a[iTerm].prereqRight; 
    pNew->wsFlags = WHERE_INDEXED;
    pNew->rSetup = 0;
    pNew->rRun = 1;
    pNew->nOut = 1;
    pNew->u.btree.nEq = 0;
    pNew->u.btree.pIndex = pWC->a[iTerm].pExpr->pIdx;
    
    rc = whereLoopInsert(pBuilder, pNew);
    *pbDone = 1;
  }else{
    *pbDone = 0;
  }
  return rc;
}

/*
** Add all WhereLoop objects for a single table of the join where 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(
................................................................................
  }else if( pSrc->notIndexed ){
    /* A NOT INDEXED clause means use the PK index */
    pProbe = pPk;
  }else{
    /* Otherwise, consider all indexes */
    pProbe = pSrc->pTab->pIndex;
  }

  rc = whereLoopAddMatch(pBuilder, pSrc, mExtra, &b);
  if( b ) return rc;
  assert( rc==SQLITE4_OK );

  rSize = whereCost(pSrc->pTab->nRowEst);
  rLogSize = estLog(rSize);

#ifndef SQLITE4_OMIT_AUTOMATIC_INDEX
  /* Automatic indexes */
  if( !pBuilder->pOrSet
................................................................................
        if( sqlite4_stricmp(z1, z2)!=0 ) continue;
      }
      obSat |= MASKBIT(i);
    }

    if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){
      Index *pPk = 0;
      if( (pIndex = pLoop->u.btree.pIndex)==0 
        || pIndex->bUnordered 
        || pIndex->eIndexType==SQLITE4_INDEX_FTS5 
      ){
        return 0;
      }else{
        isOrderDistinct = pIndex->onError!=OE_None;
        pPk = sqlite4FindPrimaryKey(pIndex->pTable, 0);
        nColumn = idxColumnCount(pIndex, pPk);
      }

................................................................................
      constructAutomaticIndex(pParse, &pWInfo->sWC, pTabItem, notReady, pLevel);
    }else
#endif
    if( pLoop->wsFlags & WHERE_INDEXED ){
      Index *pIx = pLoop->u.btree.pIndex;
      if( pIx->eIndexType==SQLITE4_INDEX_PRIMARYKEY ){
        pLevel->iIdxCur = pTabItem->iCursor;
      }else{
        /* FIXME:  As an optimization use pTabItem->iCursor if WHERE_IDX_ONLY */
        pLevel->iIdxCur = iIdxCur ? iIdxCur : pParse->nTab++;
        if( pIx->eIndexType!=SQLITE4_INDEX_FTS5 ){
          KeyInfo *pKey = sqlite4IndexKeyinfo(pParse, pIx);


          assert( pIx->pSchema==pTab->pSchema );
          assert( pLevel->iIdxCur>=0 );
          sqlite4VdbeAddOp4(v, OP_OpenRead, pLevel->iIdxCur, pIx->tnum, iDb,
              (char*)pKey, P4_KEYINFO_HANDOFF);
          VdbeComment((v, "%s", pIx->zName));
        }
      }
    }
    sqlite4CodeVerifySchema(pParse, iDb);
    notReady &= ~getMask(&pWInfo->sMaskSet, pTabItem->iCursor);
  }
  pWInfo->iTop = sqlite4VdbeCurrentAddr(v);
  if( db->mallocFailed ) goto whereBeginError;
................................................................................
          Index *pPk = sqlite4FindPrimaryKey(pTab, 0);
          pOp->p3 = pPk->tnum;
          pOp->p1 = pLevel->iIdxCur;
          pOp->opcode = OP_IdxRowkey;
        }
      }
    }

    if( (pLoop->wsFlags & WHERE_INDEXED)
     && (pLoop->u.btree.pIndex->eIndexType==SQLITE4_INDEX_FTS5)
    ){
      VdbeOp *pOp;
      VdbeOp *pEnd;

      assert( pLevel->iTabCur!=pLevel->iIdxCur );
      pOp = sqlite4VdbeGetOp(v, pWInfo->iTop);
      pEnd = &pOp[sqlite4VdbeCurrentAddr(v) - pWInfo->iTop];

      while( pOp<pEnd ){
        if( pOp->p1==pLevel->iTabCur && pOp->opcode==OP_Mifunction ){
          pOp->p1 = pLevel->iIdxCur;
        }
        pOp++;
      }
    }
  }

  /* Final cleanup
  */
  pParse->nQueryLoop = pWInfo->savedNQueryLoop;
  whereInfoFree(db, pWInfo);
  return;
}

Changes to test/permutations.test

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
#   src4
#   veryquick
#   quick
#   full
#
lappend ::testsuitelist xxx

# fts5expr1.test fts5query1.test fts5rnd1.test fts5create.test fts5snippet.test
test_suite "src4" -prefix "" -description {
} -files {
  simple.test simple2.test
  lsm1.test lsm2.test lsm3.test lsm4.test lsm5.test
  csr1.test
  ckpt1.test
  mc1.test


  alter.test alter3.test alter4.test
  analyze.test analyze3.test analyze4.test analyze5.test 
  analyze6.test analyze7.test analyze8.test
  auth.test auth2.test auth3.test auth4.test
  aggerror.test
  attach.test attach3.test attach4.test







<







>







127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#   src4
#   veryquick
#   quick
#   full
#
lappend ::testsuitelist xxx


test_suite "src4" -prefix "" -description {
} -files {
  simple.test simple2.test
  lsm1.test lsm2.test lsm3.test lsm4.test lsm5.test
  csr1.test
  ckpt1.test
  mc1.test
  fts5expr1.test fts5query1.test fts5rnd1.test fts5create.test fts5snippet.test

  alter.test alter3.test alter4.test
  analyze.test analyze3.test analyze4.test analyze5.test 
  analyze6.test analyze7.test analyze8.test
  auth.test auth2.test auth3.test auth4.test
  aggerror.test
  attach.test attach3.test attach4.test