Fossil SCM

Update to the latest NGQP changes in SQLite. Pull in all recent trunk changes.

drh 2013-06-18 20:10 UTC sqlite-NGQP merge
Commit ea308ab98bb2b49e2ecafc47bc87762be1ec9858
+1 -1
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1
-1.25
1
+1.26
22
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1 1.25
2
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1 1.26
2
+1
--- src/doc.c
+++ src/doc.c
@@ -181,10 +181,11 @@
181181
{ "mkd", 3, "text/x-markdown" },
182182
{ "mov", 3, "video/quicktime" },
183183
{ "movie", 5, "video/x-sgi-movie" },
184184
{ "mp2", 3, "audio/mpeg" },
185185
{ "mp3", 3, "audio/mpeg" },
186
+ { "mp4", 3, "video/mp4" },
186187
{ "mpe", 3, "video/mpeg" },
187188
{ "mpeg", 4, "video/mpeg" },
188189
{ "mpg", 3, "video/mpeg" },
189190
{ "mpga", 4, "audio/mpeg" },
190191
{ "ms", 2, "application/x-troff-ms" },
191192
--- src/doc.c
+++ src/doc.c
@@ -181,10 +181,11 @@
181 { "mkd", 3, "text/x-markdown" },
182 { "mov", 3, "video/quicktime" },
183 { "movie", 5, "video/x-sgi-movie" },
184 { "mp2", 3, "audio/mpeg" },
185 { "mp3", 3, "audio/mpeg" },
 
186 { "mpe", 3, "video/mpeg" },
187 { "mpeg", 4, "video/mpeg" },
188 { "mpg", 3, "video/mpeg" },
189 { "mpga", 4, "audio/mpeg" },
190 { "ms", 2, "application/x-troff-ms" },
191
--- src/doc.c
+++ src/doc.c
@@ -181,10 +181,11 @@
181 { "mkd", 3, "text/x-markdown" },
182 { "mov", 3, "video/quicktime" },
183 { "movie", 5, "video/x-sgi-movie" },
184 { "mp2", 3, "audio/mpeg" },
185 { "mp3", 3, "audio/mpeg" },
186 { "mp4", 3, "video/mp4" },
187 { "mpe", 3, "video/mpeg" },
188 { "mpeg", 4, "video/mpeg" },
189 { "mpg", 3, "video/mpeg" },
190 { "mpga", 4, "audio/mpeg" },
191 { "ms", 2, "application/x-troff-ms" },
192
+103 -84
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -670,11 +670,11 @@
670670
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
671671
** [sqlite_version()] and [sqlite_source_id()].
672672
*/
673673
#define SQLITE_VERSION "3.7.17"
674674
#define SQLITE_VERSION_NUMBER 3007017
675
-#define SQLITE_SOURCE_ID "2013-06-14 02:51:48 b920bb70bb009b7c54e7667544c9810c5ee25e19"
675
+#define SQLITE_SOURCE_ID "2013-06-18 01:52:41 4c6d58d75d51e1ce829aec214617c3a89e784a2d"
676676
677677
/*
678678
** CAPI3REF: Run-Time Library Version Numbers
679679
** KEYWORDS: sqlite3_version, sqlite3_sourceid
680680
**
@@ -76734,12 +76734,12 @@
7673476734
eType = IN_INDEX_EPH;
7673576735
if( prNotFound ){
7673676736
*prNotFound = rMayHaveNull = ++pParse->nMem;
7673776737
sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
7673876738
}else{
76739
- testcase( pParse->nQueryLoop>1 );
76740
- pParse->nQueryLoop = 1;
76739
+ testcase( pParse->nQueryLoop>0 );
76740
+ pParse->nQueryLoop = 0;
7674176741
if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){
7674276742
eType = IN_INDEX_ROWID;
7674376743
}
7674476744
}
7674576745
sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
@@ -97520,12 +97520,12 @@
9752097520
if( sqlite3ExprIsInteger(p->pLimit, &n) ){
9752197521
sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
9752297522
VdbeComment((v, "LIMIT counter"));
9752397523
if( n==0 ){
9752497524
sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
97525
- }else{
97526
- if( p->nSelectRow > n ) p->nSelectRow = n;
97525
+ }else if( n>=0 && p->nSelectRow>(u64)n ){
97526
+ p->nSelectRow = n;
9752797527
}
9752897528
}else{
9752997529
sqlite3ExprCode(pParse, p->pLimit, iLimit);
9753097530
sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
9753197531
VdbeComment((v, "LIMIT counter"));
@@ -97715,11 +97715,11 @@
9771597715
pDelete = p->pPrior;
9771697716
p->pPrior = pPrior;
9771797717
p->nSelectRow += pPrior->nSelectRow;
9771897718
if( pPrior->pLimit
9771997719
&& sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
97720
- && p->nSelectRow > nLimit
97720
+ && nLimit>0 && p->nSelectRow > (u64)nLimit
9772197721
){
9772297722
p->nSelectRow = nLimit;
9772397723
}
9772497724
if( addr ){
9772597725
sqlite3VdbeJumpHere(v, addr);
@@ -100383,11 +100383,12 @@
100383100383
** This might involve two separate loops with an OP_Sort in between, or
100384100384
** it might be a single loop that uses an index to extract information
100385100385
** in the right order to begin with.
100386100386
*/
100387100387
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
100388
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 0, 0);
100388
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0,
100389
+ WHERE_GROUPBY, 0);
100389100390
if( pWInfo==0 ) goto select_end;
100390100391
if( sqlite3WhereIsOrdered(pWInfo) ){
100391100392
/* The optimizer is able to deliver rows in group by order so
100392100393
** we do not have to sort. The OP_OpenEphemeral table will be
100393100394
** cancelled later because we still need to use the pKeyInfo
@@ -104352,11 +104353,11 @@
104352104353
** useful utility to have around when working with this module.
104353104354
*/
104354104355
typedef unsigned short int WhereCost;
104355104356
104356104357
/*
104357
-** This object contains information needed to implement a single nestd
104358
+** This object contains information needed to implement a single nested
104358104359
** loop in WHERE clause.
104359104360
**
104360104361
** Contrast this object with WhereLoop. This object describes the
104361104362
** implementation of the loop. WhereLoop describes the algorithm.
104362104363
** This object contains a pointer to the WhereLoop algorithm as one of
@@ -106328,11 +106329,10 @@
106328106329
int mxBitCol; /* Maximum column in pSrc->colUsed */
106329106330
CollSeq *pColl; /* Collating sequence to on a column */
106330106331
WhereLoop *pLoop; /* The Loop object */
106331106332
Bitmask idxCols; /* Bitmap of columns used for indexing */
106332106333
Bitmask extraCols; /* Bitmap of additional columns */
106333
- const int mxConstraint = 10; /* Maximum number of constraints */
106334106334
106335106335
/* Generate code to skip over the creation and initialization of the
106336106336
** transient index on 2nd and subsequent iterations of the loop. */
106337106337
v = pParse->pVdbe;
106338106338
assert( v!=0 );
@@ -106343,11 +106343,11 @@
106343106343
nColumn = 0;
106344106344
pTable = pSrc->pTab;
106345106345
pWCEnd = &pWC->a[pWC->nTerm];
106346106346
pLoop = pLevel->pWLoop;
106347106347
idxCols = 0;
106348
- for(pTerm=pWC->a; pTerm<pWCEnd && pLoop->nLTerm<mxConstraint; pTerm++){
106348
+ for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
106349106349
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
106350106350
int iCol = pTerm->u.leftColumn;
106351106351
Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
106352106352
testcase( iCol==BMS );
106353106353
testcase( iCol==BMS-1 );
@@ -106401,10 +106401,12 @@
106401106401
idxCols = 0;
106402106402
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
106403106403
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
106404106404
int iCol = pTerm->u.leftColumn;
106405106405
Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
106406
+ testcase( iCol==BMS-1 );
106407
+ testcase( iCol==BMS );
106406106408
if( (idxCols & cMask)==0 ){
106407106409
Expr *pX = pTerm->pExpr;
106408106410
idxCols |= cMask;
106409106411
pIdx->aiColumn[n] = pTerm->u.leftColumn;
106410106412
pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
@@ -107214,12 +107216,10 @@
107214107216
** string in this example would be set to SQLITE_AFF_NONE.
107215107217
*/
107216107218
static int codeAllEqualityTerms(
107217107219
Parse *pParse, /* Parsing context */
107218107220
WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */
107219
- WhereClause *pWC, /* The WHERE clause */
107220
- Bitmask notReady, /* Which parts of FROM have not yet been coded */
107221107221
int bRev, /* Reverse the order of IN operators */
107222107222
int nExtraReg, /* Number of extra registers to allocate */
107223107223
char **pzAff /* OUT: Set to point to affinity string */
107224107224
){
107225107225
int nEq; /* The number of == or IN constraints to code */
@@ -107335,11 +107335,10 @@
107335107335
int i, j;
107336107336
Column *aCol = pTab->aCol;
107337107337
int *aiColumn = pIndex->aiColumn;
107338107338
StrAccum txt;
107339107339
107340
- if( pIndex==0 ) return 0;
107341107340
if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
107342107341
return 0;
107343107342
}
107344107343
sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
107345107344
txt.db = db;
@@ -107402,11 +107401,11 @@
107402107401
107403107402
if( pItem->zAlias ){
107404107403
zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
107405107404
}
107406107405
if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0
107407
- && pLoop->u.btree.pIndex!=0
107406
+ && ALWAYS(pLoop->u.btree.pIndex!=0)
107408107407
){
107409107408
char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
107410107409
zMsg = sqlite3MAppendf(db, zMsg, "%s USING %s%sINDEX%s%s%s", zMsg,
107411107410
((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""),
107412107411
((flags & WHERE_IDX_ONLY)?"COVERING ":""),
@@ -107422,11 +107421,11 @@
107422107421
zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
107423107422
}else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
107424107423
zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
107425107424
}else if( flags&WHERE_BTM_LIMIT ){
107426107425
zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
107427
- }else if( flags&WHERE_TOP_LIMIT ){
107426
+ }else if( ALWAYS(flags&WHERE_TOP_LIMIT) ){
107428107427
zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
107429107428
}
107430107429
}
107431107430
#ifndef SQLITE_OMIT_VIRTUALTABLE
107432107431
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
@@ -107593,10 +107592,11 @@
107593107592
assert( omitTable==0 );
107594107593
j = 0;
107595107594
pStart = pEnd = 0;
107596107595
if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++];
107597107596
if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++];
107597
+ assert( pStart!=0 || pEnd!=0 );
107598107598
if( bRev ){
107599107599
pTerm = pStart;
107600107600
pStart = pEnd;
107601107601
pEnd = pTerm;
107602107602
}
@@ -107647,15 +107647,11 @@
107647107647
}
107648107648
start = sqlite3VdbeCurrentAddr(v);
107649107649
pLevel->op = bRev ? OP_Prev : OP_Next;
107650107650
pLevel->p1 = iCur;
107651107651
pLevel->p2 = start;
107652
- if( pStart==0 && pEnd==0 ){
107653
- pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
107654
- }else{
107655
- assert( pLevel->p5==0 );
107656
- }
107652
+ assert( pLevel->p5==0 );
107657107653
if( testOp!=OP_Noop ){
107658107654
iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
107659107655
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
107660107656
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
107661107657
sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
@@ -107762,13 +107758,11 @@
107762107758
107763107759
/* Generate code to evaluate all constraint terms using == or IN
107764107760
** and store the values of those terms in an array of registers
107765107761
** starting at regBase.
107766107762
*/
107767
- regBase = codeAllEqualityTerms(
107768
- pParse, pLevel, pWC, notReady, bRev, nExtraReg, &zStartAff
107769
- );
107763
+ regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
107770107764
zEndAff = sqlite3DbStrDup(pParse->db, zStartAff);
107771107765
addrNxt = pLevel->addrNxt;
107772107766
107773107767
/* If we are doing a reverse order scan on an ascending index, or
107774107768
** a forward order scan on a descending index, interchange the
@@ -107778,14 +107772,14 @@
107778107772
|| (bRev && pIdx->nColumn==nEq)
107779107773
){
107780107774
SWAP(WhereTerm *, pRangeEnd, pRangeStart);
107781107775
}
107782107776
107783
- testcase( pRangeStart && pRangeStart->eOperator & WO_LE );
107784
- testcase( pRangeStart && pRangeStart->eOperator & WO_GE );
107785
- testcase( pRangeEnd && pRangeEnd->eOperator & WO_LE );
107786
- testcase( pRangeEnd && pRangeEnd->eOperator & WO_GE );
107777
+ testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
107778
+ testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 );
107779
+ testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 );
107780
+ testcase( pRangeEnd && (pRangeEnd->eOperator & WO_GE)!=0 );
107787107781
startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
107788107782
endEq = !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
107789107783
start_constraints = pRangeStart || nEq>0;
107790107784
107791107785
/* Seek the index cursor to the start of the range. */
@@ -108088,12 +108082,12 @@
108088108082
** terms, set pCov to the candidate covering index. Otherwise, set
108089108083
** pCov to NULL to indicate that no candidate covering index will
108090108084
** be available.
108091108085
*/
108092108086
pSubLoop = pSubWInfo->a[0].pWLoop;
108087
+ assert( (pSubLoop->wsFlags & WHERE_TEMP_INDEX)==0 );
108093108088
if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0
108094
- && (pSubLoop->wsFlags & WHERE_TEMP_INDEX)==0
108095108089
&& (ii==0 || pSubLoop->u.btree.pIndex==pCov)
108096108090
){
108097108091
assert( pSubWInfo->a[0].iIdxCur==iCovCur );
108098108092
pCov = pSubLoop->u.btree.pIndex;
108099108093
}else{
@@ -108180,10 +108174,12 @@
108180108174
assert( !ExprHasProperty(pE, EP_FromJoin) );
108181108175
assert( (pTerm->prereqRight & newNotReady)!=0 );
108182108176
pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
108183108177
if( pAlt==0 ) continue;
108184108178
if( pAlt->wtFlags & (TERM_CODED) ) continue;
108179
+ testcase( pAlt->eOperator & WO_EQ );
108180
+ testcase( pAlt->eOperator & WO_IN );
108185108181
VdbeNoopComment((v, "begin transitive constraint"));
108186108182
sEq = *pAlt->pExpr;
108187108183
sEq.pLeft = pE->pLeft;
108188108184
sqlite3ExprIfFalse(pParse, &sEq, addrCont, SQLITE_JUMPIFNULL);
108189108185
}
@@ -108386,13 +108382,14 @@
108386108382
if( (p = pBuilder->pBest)!=0 ){
108387108383
if( p->maskSelf!=0 ){
108388108384
WhereCost rCost = whereCostAdd(p->rRun,p->rSetup);
108389108385
WhereCost rTemplate = whereCostAdd(pTemplate->rRun,pTemplate->rSetup);
108390108386
if( rCost < rTemplate ){
108387
+ testcase( rCost==rTemplate-1 );
108391108388
goto whereLoopInsert_noop;
108392108389
}
108393
- if( rCost == rTemplate && p->prereq <= pTemplate->prereq ){
108390
+ if( rCost==rTemplate && (p->prereq & pTemplate->prereq)==p->prereq ){
108394108391
goto whereLoopInsert_noop;
108395108392
}
108396108393
}
108397108394
#if WHERETRACE_ENABLED
108398108395
if( sqlite3WhereTrace & 0x8 ){
@@ -108411,11 +108408,13 @@
108411108408
if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ) continue;
108412108409
if( (p->prereq & pTemplate->prereq)==p->prereq
108413108410
&& p->rSetup<=pTemplate->rSetup
108414108411
&& p->rRun<=pTemplate->rRun
108415108412
){
108416
- /* p is equal or better than pTemplate */
108413
+ /* This branch taken when p is equal or better than pTemplate in
108414
+ ** all of (1) dependences (2) setup-cost, and (3) run-cost. */
108415
+ testcase( p->rRun==pTemplate->rRun );
108417108416
if( p->nLTerm<pTemplate->nLTerm
108418108417
&& (p->wsFlags & WHERE_INDEXED)!=0
108419108418
&& (pTemplate->wsFlags & WHERE_INDEXED)!=0
108420108419
&& p->u.btree.pIndex==pTemplate->u.btree.pIndex
108421108420
&& p->prereq==pTemplate->prereq
@@ -108436,18 +108435,28 @@
108436108435
/* pTemplate is not helpful.
108437108436
** Return without changing or adding anything */
108438108437
goto whereLoopInsert_noop;
108439108438
}
108440108439
}
108440
+ testcase( (p->prereq & pTemplate->prereq)==p->prereq
108441
+ && p->rSetup<=pTemplate->rSetup
108442
+ && p->rRun==pTemplate->rRun+1 );
108441108443
if( (p->prereq & pTemplate->prereq)==pTemplate->prereq
108442108444
&& p->rSetup>=pTemplate->rSetup
108443108445
&& p->rRun>=pTemplate->rRun
108444108446
){
108445
- /* Overwrite an existing WhereLoop with a better one */
108447
+ /* Overwrite an existing WhereLoop with a better one: one that is
108448
+ ** better at one of (1) dependences, (2) setup-cost, or (3) run-cost
108449
+ ** and is no worse in any of those categories. */
108450
+ testcase( p->rSetup==pTemplate->rSetup );
108451
+ testcase( p->rRun==pTemplate->rRun );
108446108452
pNext = p->pNextLoop;
108447108453
break;
108448108454
}
108455
+ testcase( (p->prereq & pTemplate->prereq)==pTemplate->prereq
108456
+ && p->rSetup>=pTemplate->rSetup
108457
+ && p->rRun==pTemplate->rRun-1 );
108449108458
}
108450108459
108451108460
/* If we reach this point it means that either p[] should be overwritten
108452108461
** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
108453108462
** WhereLoop and insert it.
@@ -108522,11 +108531,10 @@
108522108531
108523108532
pNew = pBuilder->pNew;
108524108533
if( db->mallocFailed ) return SQLITE_NOMEM;
108525108534
108526108535
assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
108527
- assert( pNew->u.btree.nEq<=pProbe->nColumn );
108528108536
assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
108529108537
if( pNew->wsFlags & WHERE_BTM_LIMIT ){
108530108538
opMask = WO_LT|WO_LE;
108531108539
}else if( pProbe->tnum<=0 || (pSrc->jointype & JT_LEFT)!=0 ){
108532108540
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
@@ -108533,10 +108541,11 @@
108533108541
}else{
108534108542
opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
108535108543
}
108536108544
if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
108537108545
108546
+ assert( pNew->u.btree.nEq<=pProbe->nColumn );
108538108547
if( pNew->u.btree.nEq < pProbe->nColumn ){
108539108548
iCol = pProbe->aiColumn[pNew->u.btree.nEq];
108540108549
nRowEst = whereCost(pProbe->aiRowEst[pNew->u.btree.nEq+1]);
108541108550
}else{
108542108551
iCol = -1;
@@ -108580,11 +108589,11 @@
108580108589
pNew->wsFlags |= WHERE_COLUMN_EQ;
108581108590
if( iCol<0
108582108591
|| (pProbe->onError!=OE_None && nInMul==0
108583108592
&& pNew->u.btree.nEq==pProbe->nColumn-1)
108584108593
){
108585
- testcase( pNew->wsFlags & WHERE_COLUMN_IN );
108594
+ assert( (pNew->wsFlags & WHERE_COLUMN_IN)==0 || iCol<0 );
108586108595
pNew->wsFlags |= WHERE_ONEROW;
108587108596
}
108588108597
pNew->u.btree.nEq++;
108589108598
pNew->nOut = nRowEst + nInMul;
108590108599
}else if( pTerm->eOperator & (WO_ISNULL) ){
@@ -108592,14 +108601,19 @@
108592108601
pNew->u.btree.nEq++;
108593108602
/* TUNING: IS NULL selects 2 rows */
108594108603
nIn = 10; assert( 10==whereCost(2) );
108595108604
pNew->nOut = nRowEst + nInMul + nIn;
108596108605
}else if( pTerm->eOperator & (WO_GT|WO_GE) ){
108606
+ testcase( pTerm->eOperator & WO_GT );
108607
+ testcase( pTerm->eOperator & WO_GE );
108597108608
pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
108598108609
pBtm = pTerm;
108599108610
pTop = 0;
108600
- }else if( pTerm->eOperator & (WO_LT|WO_LE) ){
108611
+ }else{
108612
+ assert( pTerm->eOperator & (WO_LT|WO_LE) );
108613
+ testcase( pTerm->eOperator & WO_LT );
108614
+ testcase( pTerm->eOperator & WO_LE );
108601108615
pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT;
108602108616
pTop = pTerm;
108603108617
pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ?
108604108618
pNew->aLTerm[pNew->nLTerm-2] : 0;
108605108619
}
@@ -108612,10 +108626,12 @@
108612108626
}
108613108627
#ifdef SQLITE_ENABLE_STAT3
108614108628
if( pNew->u.btree.nEq==1 && pProbe->nSample ){
108615108629
tRowcnt nOut = 0;
108616108630
if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){
108631
+ testcase( pTerm->eOperator & WO_EQ );
108632
+ testcase( pTerm->eOperator & WO_ISNULL );
108617108633
rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut);
108618108634
}else if( (pTerm->eOperator & WO_IN)
108619108635
&& !ExprHasProperty(pTerm->pExpr, EP_xIsSelect) ){
108620108636
rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut);
108621108637
}
@@ -108682,10 +108698,12 @@
108682108698
static Bitmask columnsInIndex(Index *pIdx){
108683108699
Bitmask m = 0;
108684108700
int j;
108685108701
for(j=pIdx->nColumn-1; j>=0; j--){
108686108702
int x = pIdx->aiColumn[j];
108703
+ testcase( x==BMS-1 );
108704
+ testcase( x==BMS-2 );
108687108705
if( x<BMS-1 ) m |= MASKBIT(x);
108688108706
}
108689108707
return m;
108690108708
}
108691108709
@@ -108855,12 +108873,11 @@
108855108873
/*
108856108874
** Add all WhereLoop objects for a table of the join identified by
108857108875
** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
108858108876
*/
108859108877
static int whereLoopAddVirtual(
108860
- WhereLoopBuilder *pBuilder, /* WHERE clause information */
108861
- Bitmask mExtra /* Extra prerequesites for using this table */
108878
+ WhereLoopBuilder *pBuilder /* WHERE clause information */
108862108879
){
108863108880
WhereInfo *pWInfo; /* WHERE analysis context */
108864108881
Parse *pParse; /* The parsing context */
108865108882
WhereClause *pWC; /* The WHERE clause */
108866108883
struct SrcList_item *pSrc; /* The FROM clause term to search */
@@ -108894,11 +108911,14 @@
108894108911
pNew->wsFlags = WHERE_VIRTUALTABLE;
108895108912
pNew->nLTerm = 0;
108896108913
pNew->u.vtab.needFree = 0;
108897108914
pUsage = pIdxInfo->aConstraintUsage;
108898108915
nConstraint = pIdxInfo->nConstraint;
108899
- if( whereLoopResize(db, pNew, nConstraint) ) return SQLITE_NOMEM;
108916
+ if( whereLoopResize(db, pNew, nConstraint) ){
108917
+ sqlite3DbFree(db, pIdxInfo);
108918
+ return SQLITE_NOMEM;
108919
+ }
108900108920
108901108921
for(iPhase=0; iPhase<=3; iPhase++){
108902108922
if( !seenIn && (iPhase&1)!=0 ){
108903108923
iPhase++;
108904108924
if( iPhase>3 ) break;
@@ -108911,13 +108931,14 @@
108911108931
switch( iPhase ){
108912108932
case 0: /* Constants without IN operator */
108913108933
pIdxCons->usable = 0;
108914108934
if( (pTerm->eOperator & WO_IN)!=0 ){
108915108935
seenIn = 1;
108916
- }else if( pTerm->prereqRight!=0 ){
108936
+ }
108937
+ if( pTerm->prereqRight!=0 ){
108917108938
seenVar = 1;
108918
- }else{
108939
+ }else if( (pTerm->eOperator & WO_IN)==0 ){
108919108940
pIdxCons->usable = 1;
108920108941
}
108921108942
break;
108922108943
case 1: /* Constants with IN operators */
108923108944
assert( seenIn );
@@ -108958,15 +108979,20 @@
108958108979
){
108959108980
rc = SQLITE_ERROR;
108960108981
sqlite3ErrorMsg(pParse, "%s.xBestIndex() malfunction", pTab->zName);
108961108982
goto whereLoopAddVtab_exit;
108962108983
}
108984
+ testcase( iTerm==nConstraint-1 );
108985
+ testcase( j==0 );
108986
+ testcase( j==pWC->nTerm-1 );
108963108987
pTerm = &pWC->a[j];
108964108988
pNew->prereq |= pTerm->prereqRight;
108965108989
assert( iTerm<pNew->nLSlot );
108966108990
pNew->aLTerm[iTerm] = pTerm;
108967108991
if( iTerm>mxTerm ) mxTerm = iTerm;
108992
+ testcase( iTerm==15 );
108993
+ testcase( iTerm==16 );
108968108994
if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<<iTerm;
108969108995
if( (pTerm->eOperator & WO_IN)!=0 ){
108970108996
if( pUsage[i].omit==0 ){
108971108997
/* Do not attempt to use an IN constraint if the virtual table
108972108998
** says that the equivalent EQ constraint cannot be safely omitted.
@@ -109066,11 +109092,11 @@
109066109092
sBest.maskSelf = 0;
109067109093
sBest.rSetup = 0;
109068109094
sBest.rRun = 0;
109069109095
#ifndef SQLITE_OMIT_VIRTUALTABLE
109070109096
if( IsVirtual(pItem->pTab) ){
109071
- rc = whereLoopAddVirtual(&sSubBuild, mExtra);
109097
+ rc = whereLoopAddVirtual(&sSubBuild);
109072109098
}else
109073109099
#endif
109074109100
{
109075109101
rc = whereLoopAddBtree(&sSubBuild, mExtra);
109076109102
}
@@ -109123,11 +109149,11 @@
109123109149
if( ((pItem->jointype|priorJoinType) & (JT_LEFT|JT_CROSS))!=0 ){
109124109150
mExtra = mPrior;
109125109151
}
109126109152
priorJoinType = pItem->jointype;
109127109153
if( IsVirtual(pItem->pTab) ){
109128
- rc = whereLoopAddVirtual(pBuilder, mExtra);
109154
+ rc = whereLoopAddVirtual(pBuilder);
109129109155
}else{
109130109156
rc = whereLoopAddBtree(pBuilder, mExtra);
109131109157
}
109132109158
if( rc==SQLITE_OK ){
109133109159
rc = whereLoopAddOr(pBuilder, mExtra);
@@ -109153,11 +109179,10 @@
109153109179
WhereInfo *pWInfo, /* The WHERE clause */
109154109180
ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */
109155109181
WherePath *pPath, /* The WherePath to check */
109156109182
u16 wctrlFlags, /* Might contain WHERE_GROUPBY or WHERE_DISTINCTBY */
109157109183
u16 nLoop, /* Number of entries in pPath->aLoop[] */
109158
- u8 isLastLoop, /* True if pLast is the inner-most loop */
109159109184
WhereLoop *pLast, /* Add this WhereLoop to the end of pPath->aLoop[] */
109160109185
Bitmask *pRevMask /* OUT: Mask of WhereLoops to run in reverse order */
109161109186
){
109162109187
u8 revSet; /* True if rev is known */
109163109188
u8 rev; /* Composite sort order */
@@ -109214,10 +109239,11 @@
109214109239
return pLast->u.vtab.isOrdered;
109215109240
}
109216109241
if( nLoop && OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0;
109217109242
109218109243
nOrderBy = pOrderBy->nExpr;
109244
+ testcase( nOrderBy==BMS-1 );
109219109245
if( nOrderBy>BMS-1 ) return 0; /* Cannot optimize overly large ORDER BYs */
109220109246
isOrderDistinct = 1;
109221109247
obDone = MASKBIT(nOrderBy)-1;
109222109248
orderDistinctMask = 0;
109223109249
ready = 0;
@@ -109238,11 +109264,11 @@
109238109264
if( pOBExpr->op!=TK_COLUMN ) continue;
109239109265
if( pOBExpr->iTable!=iCur ) continue;
109240109266
pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
109241109267
~ready, WO_EQ|WO_ISNULL, 0);
109242109268
if( pTerm==0 ) continue;
109243
- if( pOBExpr->iColumn>=0 ){
109269
+ if( (pTerm->eOperator&WO_EQ)!=0 && pOBExpr->iColumn>=0 ){
109244109270
const char *z1, *z2;
109245109271
pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
109246109272
if( !pColl ) pColl = db->pDfltColl;
109247109273
z1 = pColl->zName;
109248109274
pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
@@ -109262,34 +109288,10 @@
109262109288
}else{
109263109289
nColumn = pIndex->nColumn;
109264109290
isOrderDistinct = pIndex->onError!=OE_None;
109265109291
}
109266109292
109267
- /* For every term of the index that is constrained by == or IS NULL,
109268
- ** mark off corresponding ORDER BY terms wherever they occur
109269
- ** in the ORDER BY clause.
109270
- */
109271
- for(i=0; i<pLoop->u.btree.nEq; i++){
109272
- pTerm = pLoop->aLTerm[i];
109273
- if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))==0 ) continue;
109274
- iColumn = pTerm->u.leftColumn;
109275
- for(j=0; j<nOrderBy; j++){
109276
- if( MASKBIT(j) & obSat ) continue;
109277
- pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[j].pExpr);
109278
- if( pOBExpr->op!=TK_COLUMN ) continue;
109279
- if( pOBExpr->iTable!=iCur ) continue;
109280
- if( pOBExpr->iColumn!=iColumn ) continue;
109281
- if( iColumn>=0 ){
109282
- pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[j].pExpr);
109283
- if( !pColl ) pColl = db->pDfltColl;
109284
- if( sqlite3StrICmp(pColl->zName, pIndex->azColl[i])!=0 ) continue;
109285
- }
109286
- obSat |= MASKBIT(j);
109287
- }
109288
- if( obSat==obDone ) return 1;
109289
- }
109290
-
109291109293
/* Loop through all columns of the index and deal with the ones
109292109294
** that are not constrained by == or IN.
109293109295
*/
109294109296
rev = revSet = 0;
109295109297
distinctColumns = 0;
@@ -109298,11 +109300,14 @@
109298109300
109299109301
/* Skip over == and IS NULL terms */
109300109302
if( j<pLoop->u.btree.nEq
109301109303
&& ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
109302109304
){
109303
- if( i & WO_ISNULL ) isOrderDistinct = 0;
109305
+ if( i & WO_ISNULL ){
109306
+ testcase( isOrderDistinct );
109307
+ isOrderDistinct = 0;
109308
+ }
109304109309
continue;
109305109310
}
109306109311
109307109312
/* Get the column number in the table (iColumn) and sort order
109308109313
** (revIdx) for the j-th column of the index.
@@ -109312,10 +109317,11 @@
109312109317
iColumn = pIndex->aiColumn[j];
109313109318
revIdx = pIndex->aSortOrder[j];
109314109319
if( iColumn==pIndex->pTable->iPKey ) iColumn = -1;
109315109320
}else{
109316109321
/* The ROWID column at the end */
109322
+ assert( j==nColumn );
109317109323
iColumn = -1;
109318109324
revIdx = 0;
109319109325
}
109320109326
109321109327
/* An unconstrained column that might be NULL means that this
@@ -109335,10 +109341,12 @@
109335109341
bOnce = 1;
109336109342
isMatch = 0;
109337109343
for(i=0; bOnce && i<nOrderBy; i++){
109338109344
if( MASKBIT(i) & obSat ) continue;
109339109345
pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
109346
+ testcase( wctrlFlags & WHERE_GROUPBY );
109347
+ testcase( wctrlFlags & WHERE_DISTINCTBY );
109340109348
if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
109341109349
if( pOBExpr->op!=TK_COLUMN ) continue;
109342109350
if( pOBExpr->iTable!=iCur ) continue;
109343109351
if( pOBExpr->iColumn!=iColumn ) continue;
109344109352
if( iColumn>=0 ){
@@ -109348,11 +109356,14 @@
109348109356
}
109349109357
isMatch = 1;
109350109358
break;
109351109359
}
109352109360
if( isMatch ){
109353
- if( iColumn<0 ) distinctColumns = 1;
109361
+ if( iColumn<0 ){
109362
+ testcase( distinctColumns==0 );
109363
+ distinctColumns = 1;
109364
+ }
109354109365
obSat |= MASKBIT(i);
109355109366
if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
109356109367
/* Make sure the sort order is compatible in an ORDER BY clause.
109357109368
** Sort order is irrelevant for a GROUP BY clause. */
109358109369
if( revSet ){
@@ -109363,15 +109374,21 @@
109363109374
revSet = 1;
109364109375
}
109365109376
}
109366109377
}else{
109367109378
/* No match found */
109368
- if( j==0 || j<nColumn ) isOrderDistinct = 0;
109379
+ if( j==0 || j<nColumn ){
109380
+ testcase( isOrderDistinct!=0 );
109381
+ isOrderDistinct = 0;
109382
+ }
109369109383
break;
109370109384
}
109371109385
} /* end Loop over all index columns */
109372
- if( distinctColumns ) isOrderDistinct = 1;
109386
+ if( distinctColumns ){
109387
+ testcase( isOrderDistinct==0 );
109388
+ isOrderDistinct = 1;
109389
+ }
109373109390
} /* end-if not one-row */
109374109391
109375109392
/* Mark off any other ORDER BY terms that reference pLoop */
109376109393
if( isOrderDistinct ){
109377109394
orderDistinctMask |= pLoop->maskSelf;
@@ -109385,11 +109402,10 @@
109385109402
}
109386109403
}
109387109404
} /* End the loop over all WhereLoops from outer-most down to inner-most */
109388109405
if( obSat==obDone ) return 1;
109389109406
if( !isOrderDistinct ) return 0;
109390
- if( isLastLoop ) return 1;
109391109407
return -1;
109392109408
}
109393109409
109394109410
#ifdef WHERETRACE_ENABLED
109395109411
/* For debugging use only: */
@@ -109492,11 +109508,11 @@
109492109508
rCost = whereCostAdd(rCost, pFrom->rCost);
109493109509
maskNew = pFrom->maskLoop | pWLoop->maskSelf;
109494109510
if( !isOrderedValid ){
109495109511
switch( wherePathSatisfiesOrderBy(pWInfo,
109496109512
pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags,
109497
- iLoop, iLoop==nLoop-1, pWLoop, &revMask) ){
109513
+ iLoop, pWLoop, &revMask) ){
109498109514
case 1: /* Yes. pFrom+pWLoop does satisfy the ORDER BY clause */
109499109515
isOrdered = 1;
109500109516
isOrderedValid = 1;
109501109517
break;
109502109518
case 0: /* No. pFrom+pWLoop will require a separate sort */
@@ -109511,10 +109527,11 @@
109511109527
revMask = pFrom->revLoop;
109512109528
}
109513109529
/* Check to see if pWLoop should be added to the mxChoice best so far */
109514109530
for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){
109515109531
if( pTo->maskLoop==maskNew && pTo->isOrderedValid==isOrderedValid ){
109532
+ testcase( jj==nTo-1 );
109516109533
break;
109517109534
}
109518109535
}
109519109536
if( jj>=nTo ){
109520109537
if( nTo>=mxChoice && rCost>=mxCost ){
@@ -109554,12 +109571,14 @@
109554109571
sqlite3DebugPrintf(" vs %s cost=%-3d order=%c\n",
109555109572
wherePathName(pTo, iLoop+1, 0), pTo->rCost,
109556109573
pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?');
109557109574
}
109558109575
#endif
109576
+ testcase( pTo->rCost==rCost );
109559109577
continue;
109560109578
}
109579
+ testcase( pTo->rCost==rCost+1 );
109561109580
/* A new and better score for a previously created equivalent path */
109562109581
#ifdef WHERETRACE_ENABLED
109563109582
if( sqlite3WhereTrace&0x4 ){
109564109583
sqlite3DebugPrintf(
109565109584
"Update %s cost=%-3d order=%c",
@@ -109618,13 +109637,16 @@
109618109637
return SQLITE_ERROR;
109619109638
}
109620109639
109621109640
/* Find the lowest cost path. pFrom will be left pointing to that path */
109622109641
pFrom = aFrom;
109642
+ assert( nFrom==1 );
109643
+#if 0 /* The following is needed if nFrom is ever more than 1 */
109623109644
for(ii=1; ii<nFrom; ii++){
109624109645
if( pFrom->rCost>aFrom[ii].rCost ) pFrom = &aFrom[ii];
109625109646
}
109647
+#endif
109626109648
assert( pWInfo->nLevel==nLoop );
109627109649
/* Load the lowest cost path into pWInfo */
109628109650
for(iLoop=0; iLoop<nLoop; iLoop++){
109629109651
WhereLevel *pLevel = pWInfo->a + iLoop;
109630109652
pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop];
@@ -109635,11 +109657,11 @@
109635109657
&& pWInfo->pDistinct
109636109658
&& nRowEst
109637109659
){
109638109660
Bitmask notUsed;
109639109661
int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinct, pFrom,
109640
- WHERE_DISTINCTBY, nLoop-1, 1, pFrom->aLoop[nLoop-1], &notUsed);
109662
+ WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed);
109641109663
if( rc==1 ) pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
109642109664
}
109643109665
if( pFrom->isOrdered ){
109644109666
if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
109645109667
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
@@ -110012,11 +110034,11 @@
110012110034
}
110013110035
}
110014110036
if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
110015110037
pWInfo->revMask = (Bitmask)(-1);
110016110038
}
110017
- if( pParse->nErr || db->mallocFailed ){
110039
+ if( pParse->nErr || NEVER(db->mallocFailed) ){
110018110040
goto whereBeginError;
110019110041
}
110020110042
#ifdef WHERETRACE_ENABLED
110021110043
if( sqlite3WhereTrace ){
110022110044
int ii;
@@ -110062,11 +110084,10 @@
110062110084
/* Open all tables in the pTabList and any indices selected for
110063110085
** searching those tables.
110064110086
*/
110065110087
sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
110066110088
notReady = ~(Bitmask)0;
110067
- pWInfo->nRowOut = (WhereCost)1;
110068110089
for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
110069110090
Table *pTab; /* Table to open */
110070110091
int iDb; /* Index of database containing table/index */
110071110092
struct SrcList_item *pTabItem;
110072110093
WhereLoop *pLoop;
@@ -110089,12 +110110,12 @@
110089110110
#endif
110090110111
if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
110091110112
&& (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
110092110113
int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
110093110114
sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
110094
- testcase( pTab->nCol==BMS-1 );
110095
- testcase( pTab->nCol==BMS );
110115
+ testcase( !pWInfo->okOnePass && pTab->nCol==BMS-1 );
110116
+ testcase( !pWInfo->okOnePass && pTab->nCol==BMS );
110096110117
if( !pWInfo->okOnePass && pTab->nCol<BMS ){
110097110118
Bitmask b = pTabItem->colUsed;
110098110119
int n = 0;
110099110120
for(; b; b=b>>1, n++){}
110100110121
sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1,
@@ -110231,16 +110252,14 @@
110231110252
if( (ws & WHERE_INDEXED)!=0 && (ws & (WHERE_IPK|WHERE_TEMP_INDEX))==0 ){
110232110253
sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
110233110254
}
110234110255
}
110235110256
110236
- /* If this scan uses an index, make code substitutions to read data
110237
- ** from the index in preference to the table. Sometimes, this means
110238
- ** the table need never be read from. This is a performance boost,
110239
- ** as the vdbe level waits until the table is read before actually
110240
- ** seeking the table cursor to the record corresponding to the current
110241
- ** position in the index.
110257
+ /* If this scan uses an index, make VDBE code substitutions to read data
110258
+ ** from the index instead of from the table where possible. In some cases
110259
+ ** this optimization prevents the table from ever being read, which can
110260
+ ** yield a significant performance boost.
110242110261
**
110243110262
** Calls to the code generator in between sqlite3WhereBegin and
110244110263
** sqlite3WhereEnd will have created code that references the table
110245110264
** directly. This loop scans all that code looking for opcodes
110246110265
** that reference the table and converts them into opcodes that
110247110266
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -670,11 +670,11 @@
670 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
671 ** [sqlite_version()] and [sqlite_source_id()].
672 */
673 #define SQLITE_VERSION "3.7.17"
674 #define SQLITE_VERSION_NUMBER 3007017
675 #define SQLITE_SOURCE_ID "2013-06-14 02:51:48 b920bb70bb009b7c54e7667544c9810c5ee25e19"
676
677 /*
678 ** CAPI3REF: Run-Time Library Version Numbers
679 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
680 **
@@ -76734,12 +76734,12 @@
76734 eType = IN_INDEX_EPH;
76735 if( prNotFound ){
76736 *prNotFound = rMayHaveNull = ++pParse->nMem;
76737 sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
76738 }else{
76739 testcase( pParse->nQueryLoop>1 );
76740 pParse->nQueryLoop = 1;
76741 if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){
76742 eType = IN_INDEX_ROWID;
76743 }
76744 }
76745 sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
@@ -97520,12 +97520,12 @@
97520 if( sqlite3ExprIsInteger(p->pLimit, &n) ){
97521 sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
97522 VdbeComment((v, "LIMIT counter"));
97523 if( n==0 ){
97524 sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
97525 }else{
97526 if( p->nSelectRow > n ) p->nSelectRow = n;
97527 }
97528 }else{
97529 sqlite3ExprCode(pParse, p->pLimit, iLimit);
97530 sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
97531 VdbeComment((v, "LIMIT counter"));
@@ -97715,11 +97715,11 @@
97715 pDelete = p->pPrior;
97716 p->pPrior = pPrior;
97717 p->nSelectRow += pPrior->nSelectRow;
97718 if( pPrior->pLimit
97719 && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
97720 && p->nSelectRow > nLimit
97721 ){
97722 p->nSelectRow = nLimit;
97723 }
97724 if( addr ){
97725 sqlite3VdbeJumpHere(v, addr);
@@ -100383,11 +100383,12 @@
100383 ** This might involve two separate loops with an OP_Sort in between, or
100384 ** it might be a single loop that uses an index to extract information
100385 ** in the right order to begin with.
100386 */
100387 sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
100388 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 0, 0);
 
100389 if( pWInfo==0 ) goto select_end;
100390 if( sqlite3WhereIsOrdered(pWInfo) ){
100391 /* The optimizer is able to deliver rows in group by order so
100392 ** we do not have to sort. The OP_OpenEphemeral table will be
100393 ** cancelled later because we still need to use the pKeyInfo
@@ -104352,11 +104353,11 @@
104352 ** useful utility to have around when working with this module.
104353 */
104354 typedef unsigned short int WhereCost;
104355
104356 /*
104357 ** This object contains information needed to implement a single nestd
104358 ** loop in WHERE clause.
104359 **
104360 ** Contrast this object with WhereLoop. This object describes the
104361 ** implementation of the loop. WhereLoop describes the algorithm.
104362 ** This object contains a pointer to the WhereLoop algorithm as one of
@@ -106328,11 +106329,10 @@
106328 int mxBitCol; /* Maximum column in pSrc->colUsed */
106329 CollSeq *pColl; /* Collating sequence to on a column */
106330 WhereLoop *pLoop; /* The Loop object */
106331 Bitmask idxCols; /* Bitmap of columns used for indexing */
106332 Bitmask extraCols; /* Bitmap of additional columns */
106333 const int mxConstraint = 10; /* Maximum number of constraints */
106334
106335 /* Generate code to skip over the creation and initialization of the
106336 ** transient index on 2nd and subsequent iterations of the loop. */
106337 v = pParse->pVdbe;
106338 assert( v!=0 );
@@ -106343,11 +106343,11 @@
106343 nColumn = 0;
106344 pTable = pSrc->pTab;
106345 pWCEnd = &pWC->a[pWC->nTerm];
106346 pLoop = pLevel->pWLoop;
106347 idxCols = 0;
106348 for(pTerm=pWC->a; pTerm<pWCEnd && pLoop->nLTerm<mxConstraint; pTerm++){
106349 if( termCanDriveIndex(pTerm, pSrc, notReady) ){
106350 int iCol = pTerm->u.leftColumn;
106351 Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
106352 testcase( iCol==BMS );
106353 testcase( iCol==BMS-1 );
@@ -106401,10 +106401,12 @@
106401 idxCols = 0;
106402 for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
106403 if( termCanDriveIndex(pTerm, pSrc, notReady) ){
106404 int iCol = pTerm->u.leftColumn;
106405 Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
 
 
106406 if( (idxCols & cMask)==0 ){
106407 Expr *pX = pTerm->pExpr;
106408 idxCols |= cMask;
106409 pIdx->aiColumn[n] = pTerm->u.leftColumn;
106410 pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
@@ -107214,12 +107216,10 @@
107214 ** string in this example would be set to SQLITE_AFF_NONE.
107215 */
107216 static int codeAllEqualityTerms(
107217 Parse *pParse, /* Parsing context */
107218 WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */
107219 WhereClause *pWC, /* The WHERE clause */
107220 Bitmask notReady, /* Which parts of FROM have not yet been coded */
107221 int bRev, /* Reverse the order of IN operators */
107222 int nExtraReg, /* Number of extra registers to allocate */
107223 char **pzAff /* OUT: Set to point to affinity string */
107224 ){
107225 int nEq; /* The number of == or IN constraints to code */
@@ -107335,11 +107335,10 @@
107335 int i, j;
107336 Column *aCol = pTab->aCol;
107337 int *aiColumn = pIndex->aiColumn;
107338 StrAccum txt;
107339
107340 if( pIndex==0 ) return 0;
107341 if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
107342 return 0;
107343 }
107344 sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
107345 txt.db = db;
@@ -107402,11 +107401,11 @@
107402
107403 if( pItem->zAlias ){
107404 zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
107405 }
107406 if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0
107407 && pLoop->u.btree.pIndex!=0
107408 ){
107409 char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
107410 zMsg = sqlite3MAppendf(db, zMsg, "%s USING %s%sINDEX%s%s%s", zMsg,
107411 ((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""),
107412 ((flags & WHERE_IDX_ONLY)?"COVERING ":""),
@@ -107422,11 +107421,11 @@
107422 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
107423 }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
107424 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
107425 }else if( flags&WHERE_BTM_LIMIT ){
107426 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
107427 }else if( flags&WHERE_TOP_LIMIT ){
107428 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
107429 }
107430 }
107431 #ifndef SQLITE_OMIT_VIRTUALTABLE
107432 else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
@@ -107593,10 +107592,11 @@
107593 assert( omitTable==0 );
107594 j = 0;
107595 pStart = pEnd = 0;
107596 if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++];
107597 if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++];
 
107598 if( bRev ){
107599 pTerm = pStart;
107600 pStart = pEnd;
107601 pEnd = pTerm;
107602 }
@@ -107647,15 +107647,11 @@
107647 }
107648 start = sqlite3VdbeCurrentAddr(v);
107649 pLevel->op = bRev ? OP_Prev : OP_Next;
107650 pLevel->p1 = iCur;
107651 pLevel->p2 = start;
107652 if( pStart==0 && pEnd==0 ){
107653 pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
107654 }else{
107655 assert( pLevel->p5==0 );
107656 }
107657 if( testOp!=OP_Noop ){
107658 iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
107659 sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
107660 sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
107661 sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
@@ -107762,13 +107758,11 @@
107762
107763 /* Generate code to evaluate all constraint terms using == or IN
107764 ** and store the values of those terms in an array of registers
107765 ** starting at regBase.
107766 */
107767 regBase = codeAllEqualityTerms(
107768 pParse, pLevel, pWC, notReady, bRev, nExtraReg, &zStartAff
107769 );
107770 zEndAff = sqlite3DbStrDup(pParse->db, zStartAff);
107771 addrNxt = pLevel->addrNxt;
107772
107773 /* If we are doing a reverse order scan on an ascending index, or
107774 ** a forward order scan on a descending index, interchange the
@@ -107778,14 +107772,14 @@
107778 || (bRev && pIdx->nColumn==nEq)
107779 ){
107780 SWAP(WhereTerm *, pRangeEnd, pRangeStart);
107781 }
107782
107783 testcase( pRangeStart && pRangeStart->eOperator & WO_LE );
107784 testcase( pRangeStart && pRangeStart->eOperator & WO_GE );
107785 testcase( pRangeEnd && pRangeEnd->eOperator & WO_LE );
107786 testcase( pRangeEnd && pRangeEnd->eOperator & WO_GE );
107787 startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
107788 endEq = !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
107789 start_constraints = pRangeStart || nEq>0;
107790
107791 /* Seek the index cursor to the start of the range. */
@@ -108088,12 +108082,12 @@
108088 ** terms, set pCov to the candidate covering index. Otherwise, set
108089 ** pCov to NULL to indicate that no candidate covering index will
108090 ** be available.
108091 */
108092 pSubLoop = pSubWInfo->a[0].pWLoop;
 
108093 if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0
108094 && (pSubLoop->wsFlags & WHERE_TEMP_INDEX)==0
108095 && (ii==0 || pSubLoop->u.btree.pIndex==pCov)
108096 ){
108097 assert( pSubWInfo->a[0].iIdxCur==iCovCur );
108098 pCov = pSubLoop->u.btree.pIndex;
108099 }else{
@@ -108180,10 +108174,12 @@
108180 assert( !ExprHasProperty(pE, EP_FromJoin) );
108181 assert( (pTerm->prereqRight & newNotReady)!=0 );
108182 pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
108183 if( pAlt==0 ) continue;
108184 if( pAlt->wtFlags & (TERM_CODED) ) continue;
 
 
108185 VdbeNoopComment((v, "begin transitive constraint"));
108186 sEq = *pAlt->pExpr;
108187 sEq.pLeft = pE->pLeft;
108188 sqlite3ExprIfFalse(pParse, &sEq, addrCont, SQLITE_JUMPIFNULL);
108189 }
@@ -108386,13 +108382,14 @@
108386 if( (p = pBuilder->pBest)!=0 ){
108387 if( p->maskSelf!=0 ){
108388 WhereCost rCost = whereCostAdd(p->rRun,p->rSetup);
108389 WhereCost rTemplate = whereCostAdd(pTemplate->rRun,pTemplate->rSetup);
108390 if( rCost < rTemplate ){
 
108391 goto whereLoopInsert_noop;
108392 }
108393 if( rCost == rTemplate && p->prereq <= pTemplate->prereq ){
108394 goto whereLoopInsert_noop;
108395 }
108396 }
108397 #if WHERETRACE_ENABLED
108398 if( sqlite3WhereTrace & 0x8 ){
@@ -108411,11 +108408,13 @@
108411 if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ) continue;
108412 if( (p->prereq & pTemplate->prereq)==p->prereq
108413 && p->rSetup<=pTemplate->rSetup
108414 && p->rRun<=pTemplate->rRun
108415 ){
108416 /* p is equal or better than pTemplate */
 
 
108417 if( p->nLTerm<pTemplate->nLTerm
108418 && (p->wsFlags & WHERE_INDEXED)!=0
108419 && (pTemplate->wsFlags & WHERE_INDEXED)!=0
108420 && p->u.btree.pIndex==pTemplate->u.btree.pIndex
108421 && p->prereq==pTemplate->prereq
@@ -108436,18 +108435,28 @@
108436 /* pTemplate is not helpful.
108437 ** Return without changing or adding anything */
108438 goto whereLoopInsert_noop;
108439 }
108440 }
 
 
 
108441 if( (p->prereq & pTemplate->prereq)==pTemplate->prereq
108442 && p->rSetup>=pTemplate->rSetup
108443 && p->rRun>=pTemplate->rRun
108444 ){
108445 /* Overwrite an existing WhereLoop with a better one */
 
 
 
 
108446 pNext = p->pNextLoop;
108447 break;
108448 }
 
 
 
108449 }
108450
108451 /* If we reach this point it means that either p[] should be overwritten
108452 ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
108453 ** WhereLoop and insert it.
@@ -108522,11 +108531,10 @@
108522
108523 pNew = pBuilder->pNew;
108524 if( db->mallocFailed ) return SQLITE_NOMEM;
108525
108526 assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
108527 assert( pNew->u.btree.nEq<=pProbe->nColumn );
108528 assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
108529 if( pNew->wsFlags & WHERE_BTM_LIMIT ){
108530 opMask = WO_LT|WO_LE;
108531 }else if( pProbe->tnum<=0 || (pSrc->jointype & JT_LEFT)!=0 ){
108532 opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
@@ -108533,10 +108541,11 @@
108533 }else{
108534 opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
108535 }
108536 if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
108537
 
108538 if( pNew->u.btree.nEq < pProbe->nColumn ){
108539 iCol = pProbe->aiColumn[pNew->u.btree.nEq];
108540 nRowEst = whereCost(pProbe->aiRowEst[pNew->u.btree.nEq+1]);
108541 }else{
108542 iCol = -1;
@@ -108580,11 +108589,11 @@
108580 pNew->wsFlags |= WHERE_COLUMN_EQ;
108581 if( iCol<0
108582 || (pProbe->onError!=OE_None && nInMul==0
108583 && pNew->u.btree.nEq==pProbe->nColumn-1)
108584 ){
108585 testcase( pNew->wsFlags & WHERE_COLUMN_IN );
108586 pNew->wsFlags |= WHERE_ONEROW;
108587 }
108588 pNew->u.btree.nEq++;
108589 pNew->nOut = nRowEst + nInMul;
108590 }else if( pTerm->eOperator & (WO_ISNULL) ){
@@ -108592,14 +108601,19 @@
108592 pNew->u.btree.nEq++;
108593 /* TUNING: IS NULL selects 2 rows */
108594 nIn = 10; assert( 10==whereCost(2) );
108595 pNew->nOut = nRowEst + nInMul + nIn;
108596 }else if( pTerm->eOperator & (WO_GT|WO_GE) ){
 
 
108597 pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
108598 pBtm = pTerm;
108599 pTop = 0;
108600 }else if( pTerm->eOperator & (WO_LT|WO_LE) ){
 
 
 
108601 pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT;
108602 pTop = pTerm;
108603 pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ?
108604 pNew->aLTerm[pNew->nLTerm-2] : 0;
108605 }
@@ -108612,10 +108626,12 @@
108612 }
108613 #ifdef SQLITE_ENABLE_STAT3
108614 if( pNew->u.btree.nEq==1 && pProbe->nSample ){
108615 tRowcnt nOut = 0;
108616 if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){
 
 
108617 rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut);
108618 }else if( (pTerm->eOperator & WO_IN)
108619 && !ExprHasProperty(pTerm->pExpr, EP_xIsSelect) ){
108620 rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut);
108621 }
@@ -108682,10 +108698,12 @@
108682 static Bitmask columnsInIndex(Index *pIdx){
108683 Bitmask m = 0;
108684 int j;
108685 for(j=pIdx->nColumn-1; j>=0; j--){
108686 int x = pIdx->aiColumn[j];
 
 
108687 if( x<BMS-1 ) m |= MASKBIT(x);
108688 }
108689 return m;
108690 }
108691
@@ -108855,12 +108873,11 @@
108855 /*
108856 ** Add all WhereLoop objects for a table of the join identified by
108857 ** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
108858 */
108859 static int whereLoopAddVirtual(
108860 WhereLoopBuilder *pBuilder, /* WHERE clause information */
108861 Bitmask mExtra /* Extra prerequesites for using this table */
108862 ){
108863 WhereInfo *pWInfo; /* WHERE analysis context */
108864 Parse *pParse; /* The parsing context */
108865 WhereClause *pWC; /* The WHERE clause */
108866 struct SrcList_item *pSrc; /* The FROM clause term to search */
@@ -108894,11 +108911,14 @@
108894 pNew->wsFlags = WHERE_VIRTUALTABLE;
108895 pNew->nLTerm = 0;
108896 pNew->u.vtab.needFree = 0;
108897 pUsage = pIdxInfo->aConstraintUsage;
108898 nConstraint = pIdxInfo->nConstraint;
108899 if( whereLoopResize(db, pNew, nConstraint) ) return SQLITE_NOMEM;
 
 
 
108900
108901 for(iPhase=0; iPhase<=3; iPhase++){
108902 if( !seenIn && (iPhase&1)!=0 ){
108903 iPhase++;
108904 if( iPhase>3 ) break;
@@ -108911,13 +108931,14 @@
108911 switch( iPhase ){
108912 case 0: /* Constants without IN operator */
108913 pIdxCons->usable = 0;
108914 if( (pTerm->eOperator & WO_IN)!=0 ){
108915 seenIn = 1;
108916 }else if( pTerm->prereqRight!=0 ){
 
108917 seenVar = 1;
108918 }else{
108919 pIdxCons->usable = 1;
108920 }
108921 break;
108922 case 1: /* Constants with IN operators */
108923 assert( seenIn );
@@ -108958,15 +108979,20 @@
108958 ){
108959 rc = SQLITE_ERROR;
108960 sqlite3ErrorMsg(pParse, "%s.xBestIndex() malfunction", pTab->zName);
108961 goto whereLoopAddVtab_exit;
108962 }
 
 
 
108963 pTerm = &pWC->a[j];
108964 pNew->prereq |= pTerm->prereqRight;
108965 assert( iTerm<pNew->nLSlot );
108966 pNew->aLTerm[iTerm] = pTerm;
108967 if( iTerm>mxTerm ) mxTerm = iTerm;
 
 
108968 if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<<iTerm;
108969 if( (pTerm->eOperator & WO_IN)!=0 ){
108970 if( pUsage[i].omit==0 ){
108971 /* Do not attempt to use an IN constraint if the virtual table
108972 ** says that the equivalent EQ constraint cannot be safely omitted.
@@ -109066,11 +109092,11 @@
109066 sBest.maskSelf = 0;
109067 sBest.rSetup = 0;
109068 sBest.rRun = 0;
109069 #ifndef SQLITE_OMIT_VIRTUALTABLE
109070 if( IsVirtual(pItem->pTab) ){
109071 rc = whereLoopAddVirtual(&sSubBuild, mExtra);
109072 }else
109073 #endif
109074 {
109075 rc = whereLoopAddBtree(&sSubBuild, mExtra);
109076 }
@@ -109123,11 +109149,11 @@
109123 if( ((pItem->jointype|priorJoinType) & (JT_LEFT|JT_CROSS))!=0 ){
109124 mExtra = mPrior;
109125 }
109126 priorJoinType = pItem->jointype;
109127 if( IsVirtual(pItem->pTab) ){
109128 rc = whereLoopAddVirtual(pBuilder, mExtra);
109129 }else{
109130 rc = whereLoopAddBtree(pBuilder, mExtra);
109131 }
109132 if( rc==SQLITE_OK ){
109133 rc = whereLoopAddOr(pBuilder, mExtra);
@@ -109153,11 +109179,10 @@
109153 WhereInfo *pWInfo, /* The WHERE clause */
109154 ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */
109155 WherePath *pPath, /* The WherePath to check */
109156 u16 wctrlFlags, /* Might contain WHERE_GROUPBY or WHERE_DISTINCTBY */
109157 u16 nLoop, /* Number of entries in pPath->aLoop[] */
109158 u8 isLastLoop, /* True if pLast is the inner-most loop */
109159 WhereLoop *pLast, /* Add this WhereLoop to the end of pPath->aLoop[] */
109160 Bitmask *pRevMask /* OUT: Mask of WhereLoops to run in reverse order */
109161 ){
109162 u8 revSet; /* True if rev is known */
109163 u8 rev; /* Composite sort order */
@@ -109214,10 +109239,11 @@
109214 return pLast->u.vtab.isOrdered;
109215 }
109216 if( nLoop && OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0;
109217
109218 nOrderBy = pOrderBy->nExpr;
 
109219 if( nOrderBy>BMS-1 ) return 0; /* Cannot optimize overly large ORDER BYs */
109220 isOrderDistinct = 1;
109221 obDone = MASKBIT(nOrderBy)-1;
109222 orderDistinctMask = 0;
109223 ready = 0;
@@ -109238,11 +109264,11 @@
109238 if( pOBExpr->op!=TK_COLUMN ) continue;
109239 if( pOBExpr->iTable!=iCur ) continue;
109240 pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
109241 ~ready, WO_EQ|WO_ISNULL, 0);
109242 if( pTerm==0 ) continue;
109243 if( pOBExpr->iColumn>=0 ){
109244 const char *z1, *z2;
109245 pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
109246 if( !pColl ) pColl = db->pDfltColl;
109247 z1 = pColl->zName;
109248 pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
@@ -109262,34 +109288,10 @@
109262 }else{
109263 nColumn = pIndex->nColumn;
109264 isOrderDistinct = pIndex->onError!=OE_None;
109265 }
109266
109267 /* For every term of the index that is constrained by == or IS NULL,
109268 ** mark off corresponding ORDER BY terms wherever they occur
109269 ** in the ORDER BY clause.
109270 */
109271 for(i=0; i<pLoop->u.btree.nEq; i++){
109272 pTerm = pLoop->aLTerm[i];
109273 if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))==0 ) continue;
109274 iColumn = pTerm->u.leftColumn;
109275 for(j=0; j<nOrderBy; j++){
109276 if( MASKBIT(j) & obSat ) continue;
109277 pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[j].pExpr);
109278 if( pOBExpr->op!=TK_COLUMN ) continue;
109279 if( pOBExpr->iTable!=iCur ) continue;
109280 if( pOBExpr->iColumn!=iColumn ) continue;
109281 if( iColumn>=0 ){
109282 pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[j].pExpr);
109283 if( !pColl ) pColl = db->pDfltColl;
109284 if( sqlite3StrICmp(pColl->zName, pIndex->azColl[i])!=0 ) continue;
109285 }
109286 obSat |= MASKBIT(j);
109287 }
109288 if( obSat==obDone ) return 1;
109289 }
109290
109291 /* Loop through all columns of the index and deal with the ones
109292 ** that are not constrained by == or IN.
109293 */
109294 rev = revSet = 0;
109295 distinctColumns = 0;
@@ -109298,11 +109300,14 @@
109298
109299 /* Skip over == and IS NULL terms */
109300 if( j<pLoop->u.btree.nEq
109301 && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
109302 ){
109303 if( i & WO_ISNULL ) isOrderDistinct = 0;
 
 
 
109304 continue;
109305 }
109306
109307 /* Get the column number in the table (iColumn) and sort order
109308 ** (revIdx) for the j-th column of the index.
@@ -109312,10 +109317,11 @@
109312 iColumn = pIndex->aiColumn[j];
109313 revIdx = pIndex->aSortOrder[j];
109314 if( iColumn==pIndex->pTable->iPKey ) iColumn = -1;
109315 }else{
109316 /* The ROWID column at the end */
 
109317 iColumn = -1;
109318 revIdx = 0;
109319 }
109320
109321 /* An unconstrained column that might be NULL means that this
@@ -109335,10 +109341,12 @@
109335 bOnce = 1;
109336 isMatch = 0;
109337 for(i=0; bOnce && i<nOrderBy; i++){
109338 if( MASKBIT(i) & obSat ) continue;
109339 pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
 
 
109340 if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
109341 if( pOBExpr->op!=TK_COLUMN ) continue;
109342 if( pOBExpr->iTable!=iCur ) continue;
109343 if( pOBExpr->iColumn!=iColumn ) continue;
109344 if( iColumn>=0 ){
@@ -109348,11 +109356,14 @@
109348 }
109349 isMatch = 1;
109350 break;
109351 }
109352 if( isMatch ){
109353 if( iColumn<0 ) distinctColumns = 1;
 
 
 
109354 obSat |= MASKBIT(i);
109355 if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
109356 /* Make sure the sort order is compatible in an ORDER BY clause.
109357 ** Sort order is irrelevant for a GROUP BY clause. */
109358 if( revSet ){
@@ -109363,15 +109374,21 @@
109363 revSet = 1;
109364 }
109365 }
109366 }else{
109367 /* No match found */
109368 if( j==0 || j<nColumn ) isOrderDistinct = 0;
 
 
 
109369 break;
109370 }
109371 } /* end Loop over all index columns */
109372 if( distinctColumns ) isOrderDistinct = 1;
 
 
 
109373 } /* end-if not one-row */
109374
109375 /* Mark off any other ORDER BY terms that reference pLoop */
109376 if( isOrderDistinct ){
109377 orderDistinctMask |= pLoop->maskSelf;
@@ -109385,11 +109402,10 @@
109385 }
109386 }
109387 } /* End the loop over all WhereLoops from outer-most down to inner-most */
109388 if( obSat==obDone ) return 1;
109389 if( !isOrderDistinct ) return 0;
109390 if( isLastLoop ) return 1;
109391 return -1;
109392 }
109393
109394 #ifdef WHERETRACE_ENABLED
109395 /* For debugging use only: */
@@ -109492,11 +109508,11 @@
109492 rCost = whereCostAdd(rCost, pFrom->rCost);
109493 maskNew = pFrom->maskLoop | pWLoop->maskSelf;
109494 if( !isOrderedValid ){
109495 switch( wherePathSatisfiesOrderBy(pWInfo,
109496 pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags,
109497 iLoop, iLoop==nLoop-1, pWLoop, &revMask) ){
109498 case 1: /* Yes. pFrom+pWLoop does satisfy the ORDER BY clause */
109499 isOrdered = 1;
109500 isOrderedValid = 1;
109501 break;
109502 case 0: /* No. pFrom+pWLoop will require a separate sort */
@@ -109511,10 +109527,11 @@
109511 revMask = pFrom->revLoop;
109512 }
109513 /* Check to see if pWLoop should be added to the mxChoice best so far */
109514 for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){
109515 if( pTo->maskLoop==maskNew && pTo->isOrderedValid==isOrderedValid ){
 
109516 break;
109517 }
109518 }
109519 if( jj>=nTo ){
109520 if( nTo>=mxChoice && rCost>=mxCost ){
@@ -109554,12 +109571,14 @@
109554 sqlite3DebugPrintf(" vs %s cost=%-3d order=%c\n",
109555 wherePathName(pTo, iLoop+1, 0), pTo->rCost,
109556 pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?');
109557 }
109558 #endif
 
109559 continue;
109560 }
 
109561 /* A new and better score for a previously created equivalent path */
109562 #ifdef WHERETRACE_ENABLED
109563 if( sqlite3WhereTrace&0x4 ){
109564 sqlite3DebugPrintf(
109565 "Update %s cost=%-3d order=%c",
@@ -109618,13 +109637,16 @@
109618 return SQLITE_ERROR;
109619 }
109620
109621 /* Find the lowest cost path. pFrom will be left pointing to that path */
109622 pFrom = aFrom;
 
 
109623 for(ii=1; ii<nFrom; ii++){
109624 if( pFrom->rCost>aFrom[ii].rCost ) pFrom = &aFrom[ii];
109625 }
 
109626 assert( pWInfo->nLevel==nLoop );
109627 /* Load the lowest cost path into pWInfo */
109628 for(iLoop=0; iLoop<nLoop; iLoop++){
109629 WhereLevel *pLevel = pWInfo->a + iLoop;
109630 pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop];
@@ -109635,11 +109657,11 @@
109635 && pWInfo->pDistinct
109636 && nRowEst
109637 ){
109638 Bitmask notUsed;
109639 int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinct, pFrom,
109640 WHERE_DISTINCTBY, nLoop-1, 1, pFrom->aLoop[nLoop-1], &notUsed);
109641 if( rc==1 ) pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
109642 }
109643 if( pFrom->isOrdered ){
109644 if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
109645 pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
@@ -110012,11 +110034,11 @@
110012 }
110013 }
110014 if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
110015 pWInfo->revMask = (Bitmask)(-1);
110016 }
110017 if( pParse->nErr || db->mallocFailed ){
110018 goto whereBeginError;
110019 }
110020 #ifdef WHERETRACE_ENABLED
110021 if( sqlite3WhereTrace ){
110022 int ii;
@@ -110062,11 +110084,10 @@
110062 /* Open all tables in the pTabList and any indices selected for
110063 ** searching those tables.
110064 */
110065 sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
110066 notReady = ~(Bitmask)0;
110067 pWInfo->nRowOut = (WhereCost)1;
110068 for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
110069 Table *pTab; /* Table to open */
110070 int iDb; /* Index of database containing table/index */
110071 struct SrcList_item *pTabItem;
110072 WhereLoop *pLoop;
@@ -110089,12 +110110,12 @@
110089 #endif
110090 if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
110091 && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
110092 int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
110093 sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
110094 testcase( pTab->nCol==BMS-1 );
110095 testcase( pTab->nCol==BMS );
110096 if( !pWInfo->okOnePass && pTab->nCol<BMS ){
110097 Bitmask b = pTabItem->colUsed;
110098 int n = 0;
110099 for(; b; b=b>>1, n++){}
110100 sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1,
@@ -110231,16 +110252,14 @@
110231 if( (ws & WHERE_INDEXED)!=0 && (ws & (WHERE_IPK|WHERE_TEMP_INDEX))==0 ){
110232 sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
110233 }
110234 }
110235
110236 /* If this scan uses an index, make code substitutions to read data
110237 ** from the index in preference to the table. Sometimes, this means
110238 ** the table need never be read from. This is a performance boost,
110239 ** as the vdbe level waits until the table is read before actually
110240 ** seeking the table cursor to the record corresponding to the current
110241 ** position in the index.
110242 **
110243 ** Calls to the code generator in between sqlite3WhereBegin and
110244 ** sqlite3WhereEnd will have created code that references the table
110245 ** directly. This loop scans all that code looking for opcodes
110246 ** that reference the table and converts them into opcodes that
110247
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -670,11 +670,11 @@
670 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
671 ** [sqlite_version()] and [sqlite_source_id()].
672 */
673 #define SQLITE_VERSION "3.7.17"
674 #define SQLITE_VERSION_NUMBER 3007017
675 #define SQLITE_SOURCE_ID "2013-06-18 01:52:41 4c6d58d75d51e1ce829aec214617c3a89e784a2d"
676
677 /*
678 ** CAPI3REF: Run-Time Library Version Numbers
679 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
680 **
@@ -76734,12 +76734,12 @@
76734 eType = IN_INDEX_EPH;
76735 if( prNotFound ){
76736 *prNotFound = rMayHaveNull = ++pParse->nMem;
76737 sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
76738 }else{
76739 testcase( pParse->nQueryLoop>0 );
76740 pParse->nQueryLoop = 0;
76741 if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){
76742 eType = IN_INDEX_ROWID;
76743 }
76744 }
76745 sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
@@ -97520,12 +97520,12 @@
97520 if( sqlite3ExprIsInteger(p->pLimit, &n) ){
97521 sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
97522 VdbeComment((v, "LIMIT counter"));
97523 if( n==0 ){
97524 sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
97525 }else if( n>=0 && p->nSelectRow>(u64)n ){
97526 p->nSelectRow = n;
97527 }
97528 }else{
97529 sqlite3ExprCode(pParse, p->pLimit, iLimit);
97530 sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
97531 VdbeComment((v, "LIMIT counter"));
@@ -97715,11 +97715,11 @@
97715 pDelete = p->pPrior;
97716 p->pPrior = pPrior;
97717 p->nSelectRow += pPrior->nSelectRow;
97718 if( pPrior->pLimit
97719 && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
97720 && nLimit>0 && p->nSelectRow > (u64)nLimit
97721 ){
97722 p->nSelectRow = nLimit;
97723 }
97724 if( addr ){
97725 sqlite3VdbeJumpHere(v, addr);
@@ -100383,11 +100383,12 @@
100383 ** This might involve two separate loops with an OP_Sort in between, or
100384 ** it might be a single loop that uses an index to extract information
100385 ** in the right order to begin with.
100386 */
100387 sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
100388 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0,
100389 WHERE_GROUPBY, 0);
100390 if( pWInfo==0 ) goto select_end;
100391 if( sqlite3WhereIsOrdered(pWInfo) ){
100392 /* The optimizer is able to deliver rows in group by order so
100393 ** we do not have to sort. The OP_OpenEphemeral table will be
100394 ** cancelled later because we still need to use the pKeyInfo
@@ -104352,11 +104353,11 @@
104353 ** useful utility to have around when working with this module.
104354 */
104355 typedef unsigned short int WhereCost;
104356
104357 /*
104358 ** This object contains information needed to implement a single nested
104359 ** loop in WHERE clause.
104360 **
104361 ** Contrast this object with WhereLoop. This object describes the
104362 ** implementation of the loop. WhereLoop describes the algorithm.
104363 ** This object contains a pointer to the WhereLoop algorithm as one of
@@ -106328,11 +106329,10 @@
106329 int mxBitCol; /* Maximum column in pSrc->colUsed */
106330 CollSeq *pColl; /* Collating sequence to on a column */
106331 WhereLoop *pLoop; /* The Loop object */
106332 Bitmask idxCols; /* Bitmap of columns used for indexing */
106333 Bitmask extraCols; /* Bitmap of additional columns */
 
106334
106335 /* Generate code to skip over the creation and initialization of the
106336 ** transient index on 2nd and subsequent iterations of the loop. */
106337 v = pParse->pVdbe;
106338 assert( v!=0 );
@@ -106343,11 +106343,11 @@
106343 nColumn = 0;
106344 pTable = pSrc->pTab;
106345 pWCEnd = &pWC->a[pWC->nTerm];
106346 pLoop = pLevel->pWLoop;
106347 idxCols = 0;
106348 for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
106349 if( termCanDriveIndex(pTerm, pSrc, notReady) ){
106350 int iCol = pTerm->u.leftColumn;
106351 Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
106352 testcase( iCol==BMS );
106353 testcase( iCol==BMS-1 );
@@ -106401,10 +106401,12 @@
106401 idxCols = 0;
106402 for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
106403 if( termCanDriveIndex(pTerm, pSrc, notReady) ){
106404 int iCol = pTerm->u.leftColumn;
106405 Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
106406 testcase( iCol==BMS-1 );
106407 testcase( iCol==BMS );
106408 if( (idxCols & cMask)==0 ){
106409 Expr *pX = pTerm->pExpr;
106410 idxCols |= cMask;
106411 pIdx->aiColumn[n] = pTerm->u.leftColumn;
106412 pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
@@ -107214,12 +107216,10 @@
107216 ** string in this example would be set to SQLITE_AFF_NONE.
107217 */
107218 static int codeAllEqualityTerms(
107219 Parse *pParse, /* Parsing context */
107220 WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */
 
 
107221 int bRev, /* Reverse the order of IN operators */
107222 int nExtraReg, /* Number of extra registers to allocate */
107223 char **pzAff /* OUT: Set to point to affinity string */
107224 ){
107225 int nEq; /* The number of == or IN constraints to code */
@@ -107335,11 +107335,10 @@
107335 int i, j;
107336 Column *aCol = pTab->aCol;
107337 int *aiColumn = pIndex->aiColumn;
107338 StrAccum txt;
107339
 
107340 if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
107341 return 0;
107342 }
107343 sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
107344 txt.db = db;
@@ -107402,11 +107401,11 @@
107401
107402 if( pItem->zAlias ){
107403 zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
107404 }
107405 if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0
107406 && ALWAYS(pLoop->u.btree.pIndex!=0)
107407 ){
107408 char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
107409 zMsg = sqlite3MAppendf(db, zMsg, "%s USING %s%sINDEX%s%s%s", zMsg,
107410 ((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""),
107411 ((flags & WHERE_IDX_ONLY)?"COVERING ":""),
@@ -107422,11 +107421,11 @@
107421 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
107422 }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
107423 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
107424 }else if( flags&WHERE_BTM_LIMIT ){
107425 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
107426 }else if( ALWAYS(flags&WHERE_TOP_LIMIT) ){
107427 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
107428 }
107429 }
107430 #ifndef SQLITE_OMIT_VIRTUALTABLE
107431 else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
@@ -107593,10 +107592,11 @@
107592 assert( omitTable==0 );
107593 j = 0;
107594 pStart = pEnd = 0;
107595 if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++];
107596 if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++];
107597 assert( pStart!=0 || pEnd!=0 );
107598 if( bRev ){
107599 pTerm = pStart;
107600 pStart = pEnd;
107601 pEnd = pTerm;
107602 }
@@ -107647,15 +107647,11 @@
107647 }
107648 start = sqlite3VdbeCurrentAddr(v);
107649 pLevel->op = bRev ? OP_Prev : OP_Next;
107650 pLevel->p1 = iCur;
107651 pLevel->p2 = start;
107652 assert( pLevel->p5==0 );
 
 
 
 
107653 if( testOp!=OP_Noop ){
107654 iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
107655 sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
107656 sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
107657 sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
@@ -107762,13 +107758,11 @@
107758
107759 /* Generate code to evaluate all constraint terms using == or IN
107760 ** and store the values of those terms in an array of registers
107761 ** starting at regBase.
107762 */
107763 regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
 
 
107764 zEndAff = sqlite3DbStrDup(pParse->db, zStartAff);
107765 addrNxt = pLevel->addrNxt;
107766
107767 /* If we are doing a reverse order scan on an ascending index, or
107768 ** a forward order scan on a descending index, interchange the
@@ -107778,14 +107772,14 @@
107772 || (bRev && pIdx->nColumn==nEq)
107773 ){
107774 SWAP(WhereTerm *, pRangeEnd, pRangeStart);
107775 }
107776
107777 testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
107778 testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 );
107779 testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 );
107780 testcase( pRangeEnd && (pRangeEnd->eOperator & WO_GE)!=0 );
107781 startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
107782 endEq = !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
107783 start_constraints = pRangeStart || nEq>0;
107784
107785 /* Seek the index cursor to the start of the range. */
@@ -108088,12 +108082,12 @@
108082 ** terms, set pCov to the candidate covering index. Otherwise, set
108083 ** pCov to NULL to indicate that no candidate covering index will
108084 ** be available.
108085 */
108086 pSubLoop = pSubWInfo->a[0].pWLoop;
108087 assert( (pSubLoop->wsFlags & WHERE_TEMP_INDEX)==0 );
108088 if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0
 
108089 && (ii==0 || pSubLoop->u.btree.pIndex==pCov)
108090 ){
108091 assert( pSubWInfo->a[0].iIdxCur==iCovCur );
108092 pCov = pSubLoop->u.btree.pIndex;
108093 }else{
@@ -108180,10 +108174,12 @@
108174 assert( !ExprHasProperty(pE, EP_FromJoin) );
108175 assert( (pTerm->prereqRight & newNotReady)!=0 );
108176 pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
108177 if( pAlt==0 ) continue;
108178 if( pAlt->wtFlags & (TERM_CODED) ) continue;
108179 testcase( pAlt->eOperator & WO_EQ );
108180 testcase( pAlt->eOperator & WO_IN );
108181 VdbeNoopComment((v, "begin transitive constraint"));
108182 sEq = *pAlt->pExpr;
108183 sEq.pLeft = pE->pLeft;
108184 sqlite3ExprIfFalse(pParse, &sEq, addrCont, SQLITE_JUMPIFNULL);
108185 }
@@ -108386,13 +108382,14 @@
108382 if( (p = pBuilder->pBest)!=0 ){
108383 if( p->maskSelf!=0 ){
108384 WhereCost rCost = whereCostAdd(p->rRun,p->rSetup);
108385 WhereCost rTemplate = whereCostAdd(pTemplate->rRun,pTemplate->rSetup);
108386 if( rCost < rTemplate ){
108387 testcase( rCost==rTemplate-1 );
108388 goto whereLoopInsert_noop;
108389 }
108390 if( rCost==rTemplate && (p->prereq & pTemplate->prereq)==p->prereq ){
108391 goto whereLoopInsert_noop;
108392 }
108393 }
108394 #if WHERETRACE_ENABLED
108395 if( sqlite3WhereTrace & 0x8 ){
@@ -108411,11 +108408,13 @@
108408 if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ) continue;
108409 if( (p->prereq & pTemplate->prereq)==p->prereq
108410 && p->rSetup<=pTemplate->rSetup
108411 && p->rRun<=pTemplate->rRun
108412 ){
108413 /* This branch taken when p is equal or better than pTemplate in
108414 ** all of (1) dependences (2) setup-cost, and (3) run-cost. */
108415 testcase( p->rRun==pTemplate->rRun );
108416 if( p->nLTerm<pTemplate->nLTerm
108417 && (p->wsFlags & WHERE_INDEXED)!=0
108418 && (pTemplate->wsFlags & WHERE_INDEXED)!=0
108419 && p->u.btree.pIndex==pTemplate->u.btree.pIndex
108420 && p->prereq==pTemplate->prereq
@@ -108436,18 +108435,28 @@
108435 /* pTemplate is not helpful.
108436 ** Return without changing or adding anything */
108437 goto whereLoopInsert_noop;
108438 }
108439 }
108440 testcase( (p->prereq & pTemplate->prereq)==p->prereq
108441 && p->rSetup<=pTemplate->rSetup
108442 && p->rRun==pTemplate->rRun+1 );
108443 if( (p->prereq & pTemplate->prereq)==pTemplate->prereq
108444 && p->rSetup>=pTemplate->rSetup
108445 && p->rRun>=pTemplate->rRun
108446 ){
108447 /* Overwrite an existing WhereLoop with a better one: one that is
108448 ** better at one of (1) dependences, (2) setup-cost, or (3) run-cost
108449 ** and is no worse in any of those categories. */
108450 testcase( p->rSetup==pTemplate->rSetup );
108451 testcase( p->rRun==pTemplate->rRun );
108452 pNext = p->pNextLoop;
108453 break;
108454 }
108455 testcase( (p->prereq & pTemplate->prereq)==pTemplate->prereq
108456 && p->rSetup>=pTemplate->rSetup
108457 && p->rRun==pTemplate->rRun-1 );
108458 }
108459
108460 /* If we reach this point it means that either p[] should be overwritten
108461 ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
108462 ** WhereLoop and insert it.
@@ -108522,11 +108531,10 @@
108531
108532 pNew = pBuilder->pNew;
108533 if( db->mallocFailed ) return SQLITE_NOMEM;
108534
108535 assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
 
108536 assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
108537 if( pNew->wsFlags & WHERE_BTM_LIMIT ){
108538 opMask = WO_LT|WO_LE;
108539 }else if( pProbe->tnum<=0 || (pSrc->jointype & JT_LEFT)!=0 ){
108540 opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
@@ -108533,10 +108541,11 @@
108541 }else{
108542 opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
108543 }
108544 if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
108545
108546 assert( pNew->u.btree.nEq<=pProbe->nColumn );
108547 if( pNew->u.btree.nEq < pProbe->nColumn ){
108548 iCol = pProbe->aiColumn[pNew->u.btree.nEq];
108549 nRowEst = whereCost(pProbe->aiRowEst[pNew->u.btree.nEq+1]);
108550 }else{
108551 iCol = -1;
@@ -108580,11 +108589,11 @@
108589 pNew->wsFlags |= WHERE_COLUMN_EQ;
108590 if( iCol<0
108591 || (pProbe->onError!=OE_None && nInMul==0
108592 && pNew->u.btree.nEq==pProbe->nColumn-1)
108593 ){
108594 assert( (pNew->wsFlags & WHERE_COLUMN_IN)==0 || iCol<0 );
108595 pNew->wsFlags |= WHERE_ONEROW;
108596 }
108597 pNew->u.btree.nEq++;
108598 pNew->nOut = nRowEst + nInMul;
108599 }else if( pTerm->eOperator & (WO_ISNULL) ){
@@ -108592,14 +108601,19 @@
108601 pNew->u.btree.nEq++;
108602 /* TUNING: IS NULL selects 2 rows */
108603 nIn = 10; assert( 10==whereCost(2) );
108604 pNew->nOut = nRowEst + nInMul + nIn;
108605 }else if( pTerm->eOperator & (WO_GT|WO_GE) ){
108606 testcase( pTerm->eOperator & WO_GT );
108607 testcase( pTerm->eOperator & WO_GE );
108608 pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
108609 pBtm = pTerm;
108610 pTop = 0;
108611 }else{
108612 assert( pTerm->eOperator & (WO_LT|WO_LE) );
108613 testcase( pTerm->eOperator & WO_LT );
108614 testcase( pTerm->eOperator & WO_LE );
108615 pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT;
108616 pTop = pTerm;
108617 pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ?
108618 pNew->aLTerm[pNew->nLTerm-2] : 0;
108619 }
@@ -108612,10 +108626,12 @@
108626 }
108627 #ifdef SQLITE_ENABLE_STAT3
108628 if( pNew->u.btree.nEq==1 && pProbe->nSample ){
108629 tRowcnt nOut = 0;
108630 if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){
108631 testcase( pTerm->eOperator & WO_EQ );
108632 testcase( pTerm->eOperator & WO_ISNULL );
108633 rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut);
108634 }else if( (pTerm->eOperator & WO_IN)
108635 && !ExprHasProperty(pTerm->pExpr, EP_xIsSelect) ){
108636 rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut);
108637 }
@@ -108682,10 +108698,12 @@
108698 static Bitmask columnsInIndex(Index *pIdx){
108699 Bitmask m = 0;
108700 int j;
108701 for(j=pIdx->nColumn-1; j>=0; j--){
108702 int x = pIdx->aiColumn[j];
108703 testcase( x==BMS-1 );
108704 testcase( x==BMS-2 );
108705 if( x<BMS-1 ) m |= MASKBIT(x);
108706 }
108707 return m;
108708 }
108709
@@ -108855,12 +108873,11 @@
108873 /*
108874 ** Add all WhereLoop objects for a table of the join identified by
108875 ** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
108876 */
108877 static int whereLoopAddVirtual(
108878 WhereLoopBuilder *pBuilder /* WHERE clause information */
 
108879 ){
108880 WhereInfo *pWInfo; /* WHERE analysis context */
108881 Parse *pParse; /* The parsing context */
108882 WhereClause *pWC; /* The WHERE clause */
108883 struct SrcList_item *pSrc; /* The FROM clause term to search */
@@ -108894,11 +108911,14 @@
108911 pNew->wsFlags = WHERE_VIRTUALTABLE;
108912 pNew->nLTerm = 0;
108913 pNew->u.vtab.needFree = 0;
108914 pUsage = pIdxInfo->aConstraintUsage;
108915 nConstraint = pIdxInfo->nConstraint;
108916 if( whereLoopResize(db, pNew, nConstraint) ){
108917 sqlite3DbFree(db, pIdxInfo);
108918 return SQLITE_NOMEM;
108919 }
108920
108921 for(iPhase=0; iPhase<=3; iPhase++){
108922 if( !seenIn && (iPhase&1)!=0 ){
108923 iPhase++;
108924 if( iPhase>3 ) break;
@@ -108911,13 +108931,14 @@
108931 switch( iPhase ){
108932 case 0: /* Constants without IN operator */
108933 pIdxCons->usable = 0;
108934 if( (pTerm->eOperator & WO_IN)!=0 ){
108935 seenIn = 1;
108936 }
108937 if( pTerm->prereqRight!=0 ){
108938 seenVar = 1;
108939 }else if( (pTerm->eOperator & WO_IN)==0 ){
108940 pIdxCons->usable = 1;
108941 }
108942 break;
108943 case 1: /* Constants with IN operators */
108944 assert( seenIn );
@@ -108958,15 +108979,20 @@
108979 ){
108980 rc = SQLITE_ERROR;
108981 sqlite3ErrorMsg(pParse, "%s.xBestIndex() malfunction", pTab->zName);
108982 goto whereLoopAddVtab_exit;
108983 }
108984 testcase( iTerm==nConstraint-1 );
108985 testcase( j==0 );
108986 testcase( j==pWC->nTerm-1 );
108987 pTerm = &pWC->a[j];
108988 pNew->prereq |= pTerm->prereqRight;
108989 assert( iTerm<pNew->nLSlot );
108990 pNew->aLTerm[iTerm] = pTerm;
108991 if( iTerm>mxTerm ) mxTerm = iTerm;
108992 testcase( iTerm==15 );
108993 testcase( iTerm==16 );
108994 if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<<iTerm;
108995 if( (pTerm->eOperator & WO_IN)!=0 ){
108996 if( pUsage[i].omit==0 ){
108997 /* Do not attempt to use an IN constraint if the virtual table
108998 ** says that the equivalent EQ constraint cannot be safely omitted.
@@ -109066,11 +109092,11 @@
109092 sBest.maskSelf = 0;
109093 sBest.rSetup = 0;
109094 sBest.rRun = 0;
109095 #ifndef SQLITE_OMIT_VIRTUALTABLE
109096 if( IsVirtual(pItem->pTab) ){
109097 rc = whereLoopAddVirtual(&sSubBuild);
109098 }else
109099 #endif
109100 {
109101 rc = whereLoopAddBtree(&sSubBuild, mExtra);
109102 }
@@ -109123,11 +109149,11 @@
109149 if( ((pItem->jointype|priorJoinType) & (JT_LEFT|JT_CROSS))!=0 ){
109150 mExtra = mPrior;
109151 }
109152 priorJoinType = pItem->jointype;
109153 if( IsVirtual(pItem->pTab) ){
109154 rc = whereLoopAddVirtual(pBuilder);
109155 }else{
109156 rc = whereLoopAddBtree(pBuilder, mExtra);
109157 }
109158 if( rc==SQLITE_OK ){
109159 rc = whereLoopAddOr(pBuilder, mExtra);
@@ -109153,11 +109179,10 @@
109179 WhereInfo *pWInfo, /* The WHERE clause */
109180 ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */
109181 WherePath *pPath, /* The WherePath to check */
109182 u16 wctrlFlags, /* Might contain WHERE_GROUPBY or WHERE_DISTINCTBY */
109183 u16 nLoop, /* Number of entries in pPath->aLoop[] */
 
109184 WhereLoop *pLast, /* Add this WhereLoop to the end of pPath->aLoop[] */
109185 Bitmask *pRevMask /* OUT: Mask of WhereLoops to run in reverse order */
109186 ){
109187 u8 revSet; /* True if rev is known */
109188 u8 rev; /* Composite sort order */
@@ -109214,10 +109239,11 @@
109239 return pLast->u.vtab.isOrdered;
109240 }
109241 if( nLoop && OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0;
109242
109243 nOrderBy = pOrderBy->nExpr;
109244 testcase( nOrderBy==BMS-1 );
109245 if( nOrderBy>BMS-1 ) return 0; /* Cannot optimize overly large ORDER BYs */
109246 isOrderDistinct = 1;
109247 obDone = MASKBIT(nOrderBy)-1;
109248 orderDistinctMask = 0;
109249 ready = 0;
@@ -109238,11 +109264,11 @@
109264 if( pOBExpr->op!=TK_COLUMN ) continue;
109265 if( pOBExpr->iTable!=iCur ) continue;
109266 pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
109267 ~ready, WO_EQ|WO_ISNULL, 0);
109268 if( pTerm==0 ) continue;
109269 if( (pTerm->eOperator&WO_EQ)!=0 && pOBExpr->iColumn>=0 ){
109270 const char *z1, *z2;
109271 pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
109272 if( !pColl ) pColl = db->pDfltColl;
109273 z1 = pColl->zName;
109274 pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
@@ -109262,34 +109288,10 @@
109288 }else{
109289 nColumn = pIndex->nColumn;
109290 isOrderDistinct = pIndex->onError!=OE_None;
109291 }
109292
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109293 /* Loop through all columns of the index and deal with the ones
109294 ** that are not constrained by == or IN.
109295 */
109296 rev = revSet = 0;
109297 distinctColumns = 0;
@@ -109298,11 +109300,14 @@
109300
109301 /* Skip over == and IS NULL terms */
109302 if( j<pLoop->u.btree.nEq
109303 && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
109304 ){
109305 if( i & WO_ISNULL ){
109306 testcase( isOrderDistinct );
109307 isOrderDistinct = 0;
109308 }
109309 continue;
109310 }
109311
109312 /* Get the column number in the table (iColumn) and sort order
109313 ** (revIdx) for the j-th column of the index.
@@ -109312,10 +109317,11 @@
109317 iColumn = pIndex->aiColumn[j];
109318 revIdx = pIndex->aSortOrder[j];
109319 if( iColumn==pIndex->pTable->iPKey ) iColumn = -1;
109320 }else{
109321 /* The ROWID column at the end */
109322 assert( j==nColumn );
109323 iColumn = -1;
109324 revIdx = 0;
109325 }
109326
109327 /* An unconstrained column that might be NULL means that this
@@ -109335,10 +109341,12 @@
109341 bOnce = 1;
109342 isMatch = 0;
109343 for(i=0; bOnce && i<nOrderBy; i++){
109344 if( MASKBIT(i) & obSat ) continue;
109345 pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
109346 testcase( wctrlFlags & WHERE_GROUPBY );
109347 testcase( wctrlFlags & WHERE_DISTINCTBY );
109348 if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
109349 if( pOBExpr->op!=TK_COLUMN ) continue;
109350 if( pOBExpr->iTable!=iCur ) continue;
109351 if( pOBExpr->iColumn!=iColumn ) continue;
109352 if( iColumn>=0 ){
@@ -109348,11 +109356,14 @@
109356 }
109357 isMatch = 1;
109358 break;
109359 }
109360 if( isMatch ){
109361 if( iColumn<0 ){
109362 testcase( distinctColumns==0 );
109363 distinctColumns = 1;
109364 }
109365 obSat |= MASKBIT(i);
109366 if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
109367 /* Make sure the sort order is compatible in an ORDER BY clause.
109368 ** Sort order is irrelevant for a GROUP BY clause. */
109369 if( revSet ){
@@ -109363,15 +109374,21 @@
109374 revSet = 1;
109375 }
109376 }
109377 }else{
109378 /* No match found */
109379 if( j==0 || j<nColumn ){
109380 testcase( isOrderDistinct!=0 );
109381 isOrderDistinct = 0;
109382 }
109383 break;
109384 }
109385 } /* end Loop over all index columns */
109386 if( distinctColumns ){
109387 testcase( isOrderDistinct==0 );
109388 isOrderDistinct = 1;
109389 }
109390 } /* end-if not one-row */
109391
109392 /* Mark off any other ORDER BY terms that reference pLoop */
109393 if( isOrderDistinct ){
109394 orderDistinctMask |= pLoop->maskSelf;
@@ -109385,11 +109402,10 @@
109402 }
109403 }
109404 } /* End the loop over all WhereLoops from outer-most down to inner-most */
109405 if( obSat==obDone ) return 1;
109406 if( !isOrderDistinct ) return 0;
 
109407 return -1;
109408 }
109409
109410 #ifdef WHERETRACE_ENABLED
109411 /* For debugging use only: */
@@ -109492,11 +109508,11 @@
109508 rCost = whereCostAdd(rCost, pFrom->rCost);
109509 maskNew = pFrom->maskLoop | pWLoop->maskSelf;
109510 if( !isOrderedValid ){
109511 switch( wherePathSatisfiesOrderBy(pWInfo,
109512 pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags,
109513 iLoop, pWLoop, &revMask) ){
109514 case 1: /* Yes. pFrom+pWLoop does satisfy the ORDER BY clause */
109515 isOrdered = 1;
109516 isOrderedValid = 1;
109517 break;
109518 case 0: /* No. pFrom+pWLoop will require a separate sort */
@@ -109511,10 +109527,11 @@
109527 revMask = pFrom->revLoop;
109528 }
109529 /* Check to see if pWLoop should be added to the mxChoice best so far */
109530 for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){
109531 if( pTo->maskLoop==maskNew && pTo->isOrderedValid==isOrderedValid ){
109532 testcase( jj==nTo-1 );
109533 break;
109534 }
109535 }
109536 if( jj>=nTo ){
109537 if( nTo>=mxChoice && rCost>=mxCost ){
@@ -109554,12 +109571,14 @@
109571 sqlite3DebugPrintf(" vs %s cost=%-3d order=%c\n",
109572 wherePathName(pTo, iLoop+1, 0), pTo->rCost,
109573 pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?');
109574 }
109575 #endif
109576 testcase( pTo->rCost==rCost );
109577 continue;
109578 }
109579 testcase( pTo->rCost==rCost+1 );
109580 /* A new and better score for a previously created equivalent path */
109581 #ifdef WHERETRACE_ENABLED
109582 if( sqlite3WhereTrace&0x4 ){
109583 sqlite3DebugPrintf(
109584 "Update %s cost=%-3d order=%c",
@@ -109618,13 +109637,16 @@
109637 return SQLITE_ERROR;
109638 }
109639
109640 /* Find the lowest cost path. pFrom will be left pointing to that path */
109641 pFrom = aFrom;
109642 assert( nFrom==1 );
109643 #if 0 /* The following is needed if nFrom is ever more than 1 */
109644 for(ii=1; ii<nFrom; ii++){
109645 if( pFrom->rCost>aFrom[ii].rCost ) pFrom = &aFrom[ii];
109646 }
109647 #endif
109648 assert( pWInfo->nLevel==nLoop );
109649 /* Load the lowest cost path into pWInfo */
109650 for(iLoop=0; iLoop<nLoop; iLoop++){
109651 WhereLevel *pLevel = pWInfo->a + iLoop;
109652 pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop];
@@ -109635,11 +109657,11 @@
109657 && pWInfo->pDistinct
109658 && nRowEst
109659 ){
109660 Bitmask notUsed;
109661 int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinct, pFrom,
109662 WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed);
109663 if( rc==1 ) pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
109664 }
109665 if( pFrom->isOrdered ){
109666 if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
109667 pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
@@ -110012,11 +110034,11 @@
110034 }
110035 }
110036 if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
110037 pWInfo->revMask = (Bitmask)(-1);
110038 }
110039 if( pParse->nErr || NEVER(db->mallocFailed) ){
110040 goto whereBeginError;
110041 }
110042 #ifdef WHERETRACE_ENABLED
110043 if( sqlite3WhereTrace ){
110044 int ii;
@@ -110062,11 +110084,10 @@
110084 /* Open all tables in the pTabList and any indices selected for
110085 ** searching those tables.
110086 */
110087 sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
110088 notReady = ~(Bitmask)0;
 
110089 for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
110090 Table *pTab; /* Table to open */
110091 int iDb; /* Index of database containing table/index */
110092 struct SrcList_item *pTabItem;
110093 WhereLoop *pLoop;
@@ -110089,12 +110110,12 @@
110110 #endif
110111 if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
110112 && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
110113 int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
110114 sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
110115 testcase( !pWInfo->okOnePass && pTab->nCol==BMS-1 );
110116 testcase( !pWInfo->okOnePass && pTab->nCol==BMS );
110117 if( !pWInfo->okOnePass && pTab->nCol<BMS ){
110118 Bitmask b = pTabItem->colUsed;
110119 int n = 0;
110120 for(; b; b=b>>1, n++){}
110121 sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1,
@@ -110231,16 +110252,14 @@
110252 if( (ws & WHERE_INDEXED)!=0 && (ws & (WHERE_IPK|WHERE_TEMP_INDEX))==0 ){
110253 sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
110254 }
110255 }
110256
110257 /* If this scan uses an index, make VDBE code substitutions to read data
110258 ** from the index instead of from the table where possible. In some cases
110259 ** this optimization prevents the table from ever being read, which can
110260 ** yield a significant performance boost.
 
 
110261 **
110262 ** Calls to the code generator in between sqlite3WhereBegin and
110263 ** sqlite3WhereEnd will have created code that references the table
110264 ** directly. This loop scans all that code looking for opcodes
110265 ** that reference the table and converts them into opcodes that
110266
+103 -84
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -670,11 +670,11 @@
670670
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
671671
** [sqlite_version()] and [sqlite_source_id()].
672672
*/
673673
#define SQLITE_VERSION "3.7.17"
674674
#define SQLITE_VERSION_NUMBER 3007017
675
-#define SQLITE_SOURCE_ID "2013-06-14 02:51:48 b920bb70bb009b7c54e7667544c9810c5ee25e19"
675
+#define SQLITE_SOURCE_ID "2013-06-18 01:52:41 4c6d58d75d51e1ce829aec214617c3a89e784a2d"
676676
677677
/*
678678
** CAPI3REF: Run-Time Library Version Numbers
679679
** KEYWORDS: sqlite3_version, sqlite3_sourceid
680680
**
@@ -76734,12 +76734,12 @@
7673476734
eType = IN_INDEX_EPH;
7673576735
if( prNotFound ){
7673676736
*prNotFound = rMayHaveNull = ++pParse->nMem;
7673776737
sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
7673876738
}else{
76739
- testcase( pParse->nQueryLoop>1 );
76740
- pParse->nQueryLoop = 1;
76739
+ testcase( pParse->nQueryLoop>0 );
76740
+ pParse->nQueryLoop = 0;
7674176741
if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){
7674276742
eType = IN_INDEX_ROWID;
7674376743
}
7674476744
}
7674576745
sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
@@ -97520,12 +97520,12 @@
9752097520
if( sqlite3ExprIsInteger(p->pLimit, &n) ){
9752197521
sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
9752297522
VdbeComment((v, "LIMIT counter"));
9752397523
if( n==0 ){
9752497524
sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
97525
- }else{
97526
- if( p->nSelectRow > n ) p->nSelectRow = n;
97525
+ }else if( n>=0 && p->nSelectRow>(u64)n ){
97526
+ p->nSelectRow = n;
9752797527
}
9752897528
}else{
9752997529
sqlite3ExprCode(pParse, p->pLimit, iLimit);
9753097530
sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
9753197531
VdbeComment((v, "LIMIT counter"));
@@ -97715,11 +97715,11 @@
9771597715
pDelete = p->pPrior;
9771697716
p->pPrior = pPrior;
9771797717
p->nSelectRow += pPrior->nSelectRow;
9771897718
if( pPrior->pLimit
9771997719
&& sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
97720
- && p->nSelectRow > nLimit
97720
+ && nLimit>0 && p->nSelectRow > (u64)nLimit
9772197721
){
9772297722
p->nSelectRow = nLimit;
9772397723
}
9772497724
if( addr ){
9772597725
sqlite3VdbeJumpHere(v, addr);
@@ -100383,11 +100383,12 @@
100383100383
** This might involve two separate loops with an OP_Sort in between, or
100384100384
** it might be a single loop that uses an index to extract information
100385100385
** in the right order to begin with.
100386100386
*/
100387100387
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
100388
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 0, 0);
100388
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0,
100389
+ WHERE_GROUPBY, 0);
100389100390
if( pWInfo==0 ) goto select_end;
100390100391
if( sqlite3WhereIsOrdered(pWInfo) ){
100391100392
/* The optimizer is able to deliver rows in group by order so
100392100393
** we do not have to sort. The OP_OpenEphemeral table will be
100393100394
** cancelled later because we still need to use the pKeyInfo
@@ -104352,11 +104353,11 @@
104352104353
** useful utility to have around when working with this module.
104353104354
*/
104354104355
typedef unsigned short int WhereCost;
104355104356
104356104357
/*
104357
-** This object contains information needed to implement a single nestd
104358
+** This object contains information needed to implement a single nested
104358104359
** loop in WHERE clause.
104359104360
**
104360104361
** Contrast this object with WhereLoop. This object describes the
104361104362
** implementation of the loop. WhereLoop describes the algorithm.
104362104363
** This object contains a pointer to the WhereLoop algorithm as one of
@@ -106328,11 +106329,10 @@
106328106329
int mxBitCol; /* Maximum column in pSrc->colUsed */
106329106330
CollSeq *pColl; /* Collating sequence to on a column */
106330106331
WhereLoop *pLoop; /* The Loop object */
106331106332
Bitmask idxCols; /* Bitmap of columns used for indexing */
106332106333
Bitmask extraCols; /* Bitmap of additional columns */
106333
- const int mxConstraint = 10; /* Maximum number of constraints */
106334106334
106335106335
/* Generate code to skip over the creation and initialization of the
106336106336
** transient index on 2nd and subsequent iterations of the loop. */
106337106337
v = pParse->pVdbe;
106338106338
assert( v!=0 );
@@ -106343,11 +106343,11 @@
106343106343
nColumn = 0;
106344106344
pTable = pSrc->pTab;
106345106345
pWCEnd = &pWC->a[pWC->nTerm];
106346106346
pLoop = pLevel->pWLoop;
106347106347
idxCols = 0;
106348
- for(pTerm=pWC->a; pTerm<pWCEnd && pLoop->nLTerm<mxConstraint; pTerm++){
106348
+ for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
106349106349
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
106350106350
int iCol = pTerm->u.leftColumn;
106351106351
Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
106352106352
testcase( iCol==BMS );
106353106353
testcase( iCol==BMS-1 );
@@ -106401,10 +106401,12 @@
106401106401
idxCols = 0;
106402106402
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
106403106403
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
106404106404
int iCol = pTerm->u.leftColumn;
106405106405
Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
106406
+ testcase( iCol==BMS-1 );
106407
+ testcase( iCol==BMS );
106406106408
if( (idxCols & cMask)==0 ){
106407106409
Expr *pX = pTerm->pExpr;
106408106410
idxCols |= cMask;
106409106411
pIdx->aiColumn[n] = pTerm->u.leftColumn;
106410106412
pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
@@ -107214,12 +107216,10 @@
107214107216
** string in this example would be set to SQLITE_AFF_NONE.
107215107217
*/
107216107218
static int codeAllEqualityTerms(
107217107219
Parse *pParse, /* Parsing context */
107218107220
WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */
107219
- WhereClause *pWC, /* The WHERE clause */
107220
- Bitmask notReady, /* Which parts of FROM have not yet been coded */
107221107221
int bRev, /* Reverse the order of IN operators */
107222107222
int nExtraReg, /* Number of extra registers to allocate */
107223107223
char **pzAff /* OUT: Set to point to affinity string */
107224107224
){
107225107225
int nEq; /* The number of == or IN constraints to code */
@@ -107335,11 +107335,10 @@
107335107335
int i, j;
107336107336
Column *aCol = pTab->aCol;
107337107337
int *aiColumn = pIndex->aiColumn;
107338107338
StrAccum txt;
107339107339
107340
- if( pIndex==0 ) return 0;
107341107340
if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
107342107341
return 0;
107343107342
}
107344107343
sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
107345107344
txt.db = db;
@@ -107402,11 +107401,11 @@
107402107401
107403107402
if( pItem->zAlias ){
107404107403
zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
107405107404
}
107406107405
if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0
107407
- && pLoop->u.btree.pIndex!=0
107406
+ && ALWAYS(pLoop->u.btree.pIndex!=0)
107408107407
){
107409107408
char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
107410107409
zMsg = sqlite3MAppendf(db, zMsg, "%s USING %s%sINDEX%s%s%s", zMsg,
107411107410
((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""),
107412107411
((flags & WHERE_IDX_ONLY)?"COVERING ":""),
@@ -107422,11 +107421,11 @@
107422107421
zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
107423107422
}else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
107424107423
zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
107425107424
}else if( flags&WHERE_BTM_LIMIT ){
107426107425
zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
107427
- }else if( flags&WHERE_TOP_LIMIT ){
107426
+ }else if( ALWAYS(flags&WHERE_TOP_LIMIT) ){
107428107427
zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
107429107428
}
107430107429
}
107431107430
#ifndef SQLITE_OMIT_VIRTUALTABLE
107432107431
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
@@ -107593,10 +107592,11 @@
107593107592
assert( omitTable==0 );
107594107593
j = 0;
107595107594
pStart = pEnd = 0;
107596107595
if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++];
107597107596
if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++];
107597
+ assert( pStart!=0 || pEnd!=0 );
107598107598
if( bRev ){
107599107599
pTerm = pStart;
107600107600
pStart = pEnd;
107601107601
pEnd = pTerm;
107602107602
}
@@ -107647,15 +107647,11 @@
107647107647
}
107648107648
start = sqlite3VdbeCurrentAddr(v);
107649107649
pLevel->op = bRev ? OP_Prev : OP_Next;
107650107650
pLevel->p1 = iCur;
107651107651
pLevel->p2 = start;
107652
- if( pStart==0 && pEnd==0 ){
107653
- pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
107654
- }else{
107655
- assert( pLevel->p5==0 );
107656
- }
107652
+ assert( pLevel->p5==0 );
107657107653
if( testOp!=OP_Noop ){
107658107654
iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
107659107655
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
107660107656
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
107661107657
sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
@@ -107762,13 +107758,11 @@
107762107758
107763107759
/* Generate code to evaluate all constraint terms using == or IN
107764107760
** and store the values of those terms in an array of registers
107765107761
** starting at regBase.
107766107762
*/
107767
- regBase = codeAllEqualityTerms(
107768
- pParse, pLevel, pWC, notReady, bRev, nExtraReg, &zStartAff
107769
- );
107763
+ regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
107770107764
zEndAff = sqlite3DbStrDup(pParse->db, zStartAff);
107771107765
addrNxt = pLevel->addrNxt;
107772107766
107773107767
/* If we are doing a reverse order scan on an ascending index, or
107774107768
** a forward order scan on a descending index, interchange the
@@ -107778,14 +107772,14 @@
107778107772
|| (bRev && pIdx->nColumn==nEq)
107779107773
){
107780107774
SWAP(WhereTerm *, pRangeEnd, pRangeStart);
107781107775
}
107782107776
107783
- testcase( pRangeStart && pRangeStart->eOperator & WO_LE );
107784
- testcase( pRangeStart && pRangeStart->eOperator & WO_GE );
107785
- testcase( pRangeEnd && pRangeEnd->eOperator & WO_LE );
107786
- testcase( pRangeEnd && pRangeEnd->eOperator & WO_GE );
107777
+ testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
107778
+ testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 );
107779
+ testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 );
107780
+ testcase( pRangeEnd && (pRangeEnd->eOperator & WO_GE)!=0 );
107787107781
startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
107788107782
endEq = !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
107789107783
start_constraints = pRangeStart || nEq>0;
107790107784
107791107785
/* Seek the index cursor to the start of the range. */
@@ -108088,12 +108082,12 @@
108088108082
** terms, set pCov to the candidate covering index. Otherwise, set
108089108083
** pCov to NULL to indicate that no candidate covering index will
108090108084
** be available.
108091108085
*/
108092108086
pSubLoop = pSubWInfo->a[0].pWLoop;
108087
+ assert( (pSubLoop->wsFlags & WHERE_TEMP_INDEX)==0 );
108093108088
if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0
108094
- && (pSubLoop->wsFlags & WHERE_TEMP_INDEX)==0
108095108089
&& (ii==0 || pSubLoop->u.btree.pIndex==pCov)
108096108090
){
108097108091
assert( pSubWInfo->a[0].iIdxCur==iCovCur );
108098108092
pCov = pSubLoop->u.btree.pIndex;
108099108093
}else{
@@ -108180,10 +108174,12 @@
108180108174
assert( !ExprHasProperty(pE, EP_FromJoin) );
108181108175
assert( (pTerm->prereqRight & newNotReady)!=0 );
108182108176
pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
108183108177
if( pAlt==0 ) continue;
108184108178
if( pAlt->wtFlags & (TERM_CODED) ) continue;
108179
+ testcase( pAlt->eOperator & WO_EQ );
108180
+ testcase( pAlt->eOperator & WO_IN );
108185108181
VdbeNoopComment((v, "begin transitive constraint"));
108186108182
sEq = *pAlt->pExpr;
108187108183
sEq.pLeft = pE->pLeft;
108188108184
sqlite3ExprIfFalse(pParse, &sEq, addrCont, SQLITE_JUMPIFNULL);
108189108185
}
@@ -108386,13 +108382,14 @@
108386108382
if( (p = pBuilder->pBest)!=0 ){
108387108383
if( p->maskSelf!=0 ){
108388108384
WhereCost rCost = whereCostAdd(p->rRun,p->rSetup);
108389108385
WhereCost rTemplate = whereCostAdd(pTemplate->rRun,pTemplate->rSetup);
108390108386
if( rCost < rTemplate ){
108387
+ testcase( rCost==rTemplate-1 );
108391108388
goto whereLoopInsert_noop;
108392108389
}
108393
- if( rCost == rTemplate && p->prereq <= pTemplate->prereq ){
108390
+ if( rCost==rTemplate && (p->prereq & pTemplate->prereq)==p->prereq ){
108394108391
goto whereLoopInsert_noop;
108395108392
}
108396108393
}
108397108394
#if WHERETRACE_ENABLED
108398108395
if( sqlite3WhereTrace & 0x8 ){
@@ -108411,11 +108408,13 @@
108411108408
if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ) continue;
108412108409
if( (p->prereq & pTemplate->prereq)==p->prereq
108413108410
&& p->rSetup<=pTemplate->rSetup
108414108411
&& p->rRun<=pTemplate->rRun
108415108412
){
108416
- /* p is equal or better than pTemplate */
108413
+ /* This branch taken when p is equal or better than pTemplate in
108414
+ ** all of (1) dependences (2) setup-cost, and (3) run-cost. */
108415
+ testcase( p->rRun==pTemplate->rRun );
108417108416
if( p->nLTerm<pTemplate->nLTerm
108418108417
&& (p->wsFlags & WHERE_INDEXED)!=0
108419108418
&& (pTemplate->wsFlags & WHERE_INDEXED)!=0
108420108419
&& p->u.btree.pIndex==pTemplate->u.btree.pIndex
108421108420
&& p->prereq==pTemplate->prereq
@@ -108436,18 +108435,28 @@
108436108435
/* pTemplate is not helpful.
108437108436
** Return without changing or adding anything */
108438108437
goto whereLoopInsert_noop;
108439108438
}
108440108439
}
108440
+ testcase( (p->prereq & pTemplate->prereq)==p->prereq
108441
+ && p->rSetup<=pTemplate->rSetup
108442
+ && p->rRun==pTemplate->rRun+1 );
108441108443
if( (p->prereq & pTemplate->prereq)==pTemplate->prereq
108442108444
&& p->rSetup>=pTemplate->rSetup
108443108445
&& p->rRun>=pTemplate->rRun
108444108446
){
108445
- /* Overwrite an existing WhereLoop with a better one */
108447
+ /* Overwrite an existing WhereLoop with a better one: one that is
108448
+ ** better at one of (1) dependences, (2) setup-cost, or (3) run-cost
108449
+ ** and is no worse in any of those categories. */
108450
+ testcase( p->rSetup==pTemplate->rSetup );
108451
+ testcase( p->rRun==pTemplate->rRun );
108446108452
pNext = p->pNextLoop;
108447108453
break;
108448108454
}
108455
+ testcase( (p->prereq & pTemplate->prereq)==pTemplate->prereq
108456
+ && p->rSetup>=pTemplate->rSetup
108457
+ && p->rRun==pTemplate->rRun-1 );
108449108458
}
108450108459
108451108460
/* If we reach this point it means that either p[] should be overwritten
108452108461
** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
108453108462
** WhereLoop and insert it.
@@ -108522,11 +108531,10 @@
108522108531
108523108532
pNew = pBuilder->pNew;
108524108533
if( db->mallocFailed ) return SQLITE_NOMEM;
108525108534
108526108535
assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
108527
- assert( pNew->u.btree.nEq<=pProbe->nColumn );
108528108536
assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
108529108537
if( pNew->wsFlags & WHERE_BTM_LIMIT ){
108530108538
opMask = WO_LT|WO_LE;
108531108539
}else if( pProbe->tnum<=0 || (pSrc->jointype & JT_LEFT)!=0 ){
108532108540
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
@@ -108533,10 +108541,11 @@
108533108541
}else{
108534108542
opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
108535108543
}
108536108544
if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
108537108545
108546
+ assert( pNew->u.btree.nEq<=pProbe->nColumn );
108538108547
if( pNew->u.btree.nEq < pProbe->nColumn ){
108539108548
iCol = pProbe->aiColumn[pNew->u.btree.nEq];
108540108549
nRowEst = whereCost(pProbe->aiRowEst[pNew->u.btree.nEq+1]);
108541108550
}else{
108542108551
iCol = -1;
@@ -108580,11 +108589,11 @@
108580108589
pNew->wsFlags |= WHERE_COLUMN_EQ;
108581108590
if( iCol<0
108582108591
|| (pProbe->onError!=OE_None && nInMul==0
108583108592
&& pNew->u.btree.nEq==pProbe->nColumn-1)
108584108593
){
108585
- testcase( pNew->wsFlags & WHERE_COLUMN_IN );
108594
+ assert( (pNew->wsFlags & WHERE_COLUMN_IN)==0 || iCol<0 );
108586108595
pNew->wsFlags |= WHERE_ONEROW;
108587108596
}
108588108597
pNew->u.btree.nEq++;
108589108598
pNew->nOut = nRowEst + nInMul;
108590108599
}else if( pTerm->eOperator & (WO_ISNULL) ){
@@ -108592,14 +108601,19 @@
108592108601
pNew->u.btree.nEq++;
108593108602
/* TUNING: IS NULL selects 2 rows */
108594108603
nIn = 10; assert( 10==whereCost(2) );
108595108604
pNew->nOut = nRowEst + nInMul + nIn;
108596108605
}else if( pTerm->eOperator & (WO_GT|WO_GE) ){
108606
+ testcase( pTerm->eOperator & WO_GT );
108607
+ testcase( pTerm->eOperator & WO_GE );
108597108608
pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
108598108609
pBtm = pTerm;
108599108610
pTop = 0;
108600
- }else if( pTerm->eOperator & (WO_LT|WO_LE) ){
108611
+ }else{
108612
+ assert( pTerm->eOperator & (WO_LT|WO_LE) );
108613
+ testcase( pTerm->eOperator & WO_LT );
108614
+ testcase( pTerm->eOperator & WO_LE );
108601108615
pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT;
108602108616
pTop = pTerm;
108603108617
pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ?
108604108618
pNew->aLTerm[pNew->nLTerm-2] : 0;
108605108619
}
@@ -108612,10 +108626,12 @@
108612108626
}
108613108627
#ifdef SQLITE_ENABLE_STAT3
108614108628
if( pNew->u.btree.nEq==1 && pProbe->nSample ){
108615108629
tRowcnt nOut = 0;
108616108630
if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){
108631
+ testcase( pTerm->eOperator & WO_EQ );
108632
+ testcase( pTerm->eOperator & WO_ISNULL );
108617108633
rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut);
108618108634
}else if( (pTerm->eOperator & WO_IN)
108619108635
&& !ExprHasProperty(pTerm->pExpr, EP_xIsSelect) ){
108620108636
rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut);
108621108637
}
@@ -108682,10 +108698,12 @@
108682108698
static Bitmask columnsInIndex(Index *pIdx){
108683108699
Bitmask m = 0;
108684108700
int j;
108685108701
for(j=pIdx->nColumn-1; j>=0; j--){
108686108702
int x = pIdx->aiColumn[j];
108703
+ testcase( x==BMS-1 );
108704
+ testcase( x==BMS-2 );
108687108705
if( x<BMS-1 ) m |= MASKBIT(x);
108688108706
}
108689108707
return m;
108690108708
}
108691108709
@@ -108855,12 +108873,11 @@
108855108873
/*
108856108874
** Add all WhereLoop objects for a table of the join identified by
108857108875
** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
108858108876
*/
108859108877
static int whereLoopAddVirtual(
108860
- WhereLoopBuilder *pBuilder, /* WHERE clause information */
108861
- Bitmask mExtra /* Extra prerequesites for using this table */
108878
+ WhereLoopBuilder *pBuilder /* WHERE clause information */
108862108879
){
108863108880
WhereInfo *pWInfo; /* WHERE analysis context */
108864108881
Parse *pParse; /* The parsing context */
108865108882
WhereClause *pWC; /* The WHERE clause */
108866108883
struct SrcList_item *pSrc; /* The FROM clause term to search */
@@ -108894,11 +108911,14 @@
108894108911
pNew->wsFlags = WHERE_VIRTUALTABLE;
108895108912
pNew->nLTerm = 0;
108896108913
pNew->u.vtab.needFree = 0;
108897108914
pUsage = pIdxInfo->aConstraintUsage;
108898108915
nConstraint = pIdxInfo->nConstraint;
108899
- if( whereLoopResize(db, pNew, nConstraint) ) return SQLITE_NOMEM;
108916
+ if( whereLoopResize(db, pNew, nConstraint) ){
108917
+ sqlite3DbFree(db, pIdxInfo);
108918
+ return SQLITE_NOMEM;
108919
+ }
108900108920
108901108921
for(iPhase=0; iPhase<=3; iPhase++){
108902108922
if( !seenIn && (iPhase&1)!=0 ){
108903108923
iPhase++;
108904108924
if( iPhase>3 ) break;
@@ -108911,13 +108931,14 @@
108911108931
switch( iPhase ){
108912108932
case 0: /* Constants without IN operator */
108913108933
pIdxCons->usable = 0;
108914108934
if( (pTerm->eOperator & WO_IN)!=0 ){
108915108935
seenIn = 1;
108916
- }else if( pTerm->prereqRight!=0 ){
108936
+ }
108937
+ if( pTerm->prereqRight!=0 ){
108917108938
seenVar = 1;
108918
- }else{
108939
+ }else if( (pTerm->eOperator & WO_IN)==0 ){
108919108940
pIdxCons->usable = 1;
108920108941
}
108921108942
break;
108922108943
case 1: /* Constants with IN operators */
108923108944
assert( seenIn );
@@ -108958,15 +108979,20 @@
108958108979
){
108959108980
rc = SQLITE_ERROR;
108960108981
sqlite3ErrorMsg(pParse, "%s.xBestIndex() malfunction", pTab->zName);
108961108982
goto whereLoopAddVtab_exit;
108962108983
}
108984
+ testcase( iTerm==nConstraint-1 );
108985
+ testcase( j==0 );
108986
+ testcase( j==pWC->nTerm-1 );
108963108987
pTerm = &pWC->a[j];
108964108988
pNew->prereq |= pTerm->prereqRight;
108965108989
assert( iTerm<pNew->nLSlot );
108966108990
pNew->aLTerm[iTerm] = pTerm;
108967108991
if( iTerm>mxTerm ) mxTerm = iTerm;
108992
+ testcase( iTerm==15 );
108993
+ testcase( iTerm==16 );
108968108994
if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<<iTerm;
108969108995
if( (pTerm->eOperator & WO_IN)!=0 ){
108970108996
if( pUsage[i].omit==0 ){
108971108997
/* Do not attempt to use an IN constraint if the virtual table
108972108998
** says that the equivalent EQ constraint cannot be safely omitted.
@@ -109066,11 +109092,11 @@
109066109092
sBest.maskSelf = 0;
109067109093
sBest.rSetup = 0;
109068109094
sBest.rRun = 0;
109069109095
#ifndef SQLITE_OMIT_VIRTUALTABLE
109070109096
if( IsVirtual(pItem->pTab) ){
109071
- rc = whereLoopAddVirtual(&sSubBuild, mExtra);
109097
+ rc = whereLoopAddVirtual(&sSubBuild);
109072109098
}else
109073109099
#endif
109074109100
{
109075109101
rc = whereLoopAddBtree(&sSubBuild, mExtra);
109076109102
}
@@ -109123,11 +109149,11 @@
109123109149
if( ((pItem->jointype|priorJoinType) & (JT_LEFT|JT_CROSS))!=0 ){
109124109150
mExtra = mPrior;
109125109151
}
109126109152
priorJoinType = pItem->jointype;
109127109153
if( IsVirtual(pItem->pTab) ){
109128
- rc = whereLoopAddVirtual(pBuilder, mExtra);
109154
+ rc = whereLoopAddVirtual(pBuilder);
109129109155
}else{
109130109156
rc = whereLoopAddBtree(pBuilder, mExtra);
109131109157
}
109132109158
if( rc==SQLITE_OK ){
109133109159
rc = whereLoopAddOr(pBuilder, mExtra);
@@ -109153,11 +109179,10 @@
109153109179
WhereInfo *pWInfo, /* The WHERE clause */
109154109180
ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */
109155109181
WherePath *pPath, /* The WherePath to check */
109156109182
u16 wctrlFlags, /* Might contain WHERE_GROUPBY or WHERE_DISTINCTBY */
109157109183
u16 nLoop, /* Number of entries in pPath->aLoop[] */
109158
- u8 isLastLoop, /* True if pLast is the inner-most loop */
109159109184
WhereLoop *pLast, /* Add this WhereLoop to the end of pPath->aLoop[] */
109160109185
Bitmask *pRevMask /* OUT: Mask of WhereLoops to run in reverse order */
109161109186
){
109162109187
u8 revSet; /* True if rev is known */
109163109188
u8 rev; /* Composite sort order */
@@ -109214,10 +109239,11 @@
109214109239
return pLast->u.vtab.isOrdered;
109215109240
}
109216109241
if( nLoop && OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0;
109217109242
109218109243
nOrderBy = pOrderBy->nExpr;
109244
+ testcase( nOrderBy==BMS-1 );
109219109245
if( nOrderBy>BMS-1 ) return 0; /* Cannot optimize overly large ORDER BYs */
109220109246
isOrderDistinct = 1;
109221109247
obDone = MASKBIT(nOrderBy)-1;
109222109248
orderDistinctMask = 0;
109223109249
ready = 0;
@@ -109238,11 +109264,11 @@
109238109264
if( pOBExpr->op!=TK_COLUMN ) continue;
109239109265
if( pOBExpr->iTable!=iCur ) continue;
109240109266
pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
109241109267
~ready, WO_EQ|WO_ISNULL, 0);
109242109268
if( pTerm==0 ) continue;
109243
- if( pOBExpr->iColumn>=0 ){
109269
+ if( (pTerm->eOperator&WO_EQ)!=0 && pOBExpr->iColumn>=0 ){
109244109270
const char *z1, *z2;
109245109271
pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
109246109272
if( !pColl ) pColl = db->pDfltColl;
109247109273
z1 = pColl->zName;
109248109274
pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
@@ -109262,34 +109288,10 @@
109262109288
}else{
109263109289
nColumn = pIndex->nColumn;
109264109290
isOrderDistinct = pIndex->onError!=OE_None;
109265109291
}
109266109292
109267
- /* For every term of the index that is constrained by == or IS NULL,
109268
- ** mark off corresponding ORDER BY terms wherever they occur
109269
- ** in the ORDER BY clause.
109270
- */
109271
- for(i=0; i<pLoop->u.btree.nEq; i++){
109272
- pTerm = pLoop->aLTerm[i];
109273
- if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))==0 ) continue;
109274
- iColumn = pTerm->u.leftColumn;
109275
- for(j=0; j<nOrderBy; j++){
109276
- if( MASKBIT(j) & obSat ) continue;
109277
- pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[j].pExpr);
109278
- if( pOBExpr->op!=TK_COLUMN ) continue;
109279
- if( pOBExpr->iTable!=iCur ) continue;
109280
- if( pOBExpr->iColumn!=iColumn ) continue;
109281
- if( iColumn>=0 ){
109282
- pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[j].pExpr);
109283
- if( !pColl ) pColl = db->pDfltColl;
109284
- if( sqlite3StrICmp(pColl->zName, pIndex->azColl[i])!=0 ) continue;
109285
- }
109286
- obSat |= MASKBIT(j);
109287
- }
109288
- if( obSat==obDone ) return 1;
109289
- }
109290
-
109291109293
/* Loop through all columns of the index and deal with the ones
109292109294
** that are not constrained by == or IN.
109293109295
*/
109294109296
rev = revSet = 0;
109295109297
distinctColumns = 0;
@@ -109298,11 +109300,14 @@
109298109300
109299109301
/* Skip over == and IS NULL terms */
109300109302
if( j<pLoop->u.btree.nEq
109301109303
&& ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
109302109304
){
109303
- if( i & WO_ISNULL ) isOrderDistinct = 0;
109305
+ if( i & WO_ISNULL ){
109306
+ testcase( isOrderDistinct );
109307
+ isOrderDistinct = 0;
109308
+ }
109304109309
continue;
109305109310
}
109306109311
109307109312
/* Get the column number in the table (iColumn) and sort order
109308109313
** (revIdx) for the j-th column of the index.
@@ -109312,10 +109317,11 @@
109312109317
iColumn = pIndex->aiColumn[j];
109313109318
revIdx = pIndex->aSortOrder[j];
109314109319
if( iColumn==pIndex->pTable->iPKey ) iColumn = -1;
109315109320
}else{
109316109321
/* The ROWID column at the end */
109322
+ assert( j==nColumn );
109317109323
iColumn = -1;
109318109324
revIdx = 0;
109319109325
}
109320109326
109321109327
/* An unconstrained column that might be NULL means that this
@@ -109335,10 +109341,12 @@
109335109341
bOnce = 1;
109336109342
isMatch = 0;
109337109343
for(i=0; bOnce && i<nOrderBy; i++){
109338109344
if( MASKBIT(i) & obSat ) continue;
109339109345
pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
109346
+ testcase( wctrlFlags & WHERE_GROUPBY );
109347
+ testcase( wctrlFlags & WHERE_DISTINCTBY );
109340109348
if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
109341109349
if( pOBExpr->op!=TK_COLUMN ) continue;
109342109350
if( pOBExpr->iTable!=iCur ) continue;
109343109351
if( pOBExpr->iColumn!=iColumn ) continue;
109344109352
if( iColumn>=0 ){
@@ -109348,11 +109356,14 @@
109348109356
}
109349109357
isMatch = 1;
109350109358
break;
109351109359
}
109352109360
if( isMatch ){
109353
- if( iColumn<0 ) distinctColumns = 1;
109361
+ if( iColumn<0 ){
109362
+ testcase( distinctColumns==0 );
109363
+ distinctColumns = 1;
109364
+ }
109354109365
obSat |= MASKBIT(i);
109355109366
if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
109356109367
/* Make sure the sort order is compatible in an ORDER BY clause.
109357109368
** Sort order is irrelevant for a GROUP BY clause. */
109358109369
if( revSet ){
@@ -109363,15 +109374,21 @@
109363109374
revSet = 1;
109364109375
}
109365109376
}
109366109377
}else{
109367109378
/* No match found */
109368
- if( j==0 || j<nColumn ) isOrderDistinct = 0;
109379
+ if( j==0 || j<nColumn ){
109380
+ testcase( isOrderDistinct!=0 );
109381
+ isOrderDistinct = 0;
109382
+ }
109369109383
break;
109370109384
}
109371109385
} /* end Loop over all index columns */
109372
- if( distinctColumns ) isOrderDistinct = 1;
109386
+ if( distinctColumns ){
109387
+ testcase( isOrderDistinct==0 );
109388
+ isOrderDistinct = 1;
109389
+ }
109373109390
} /* end-if not one-row */
109374109391
109375109392
/* Mark off any other ORDER BY terms that reference pLoop */
109376109393
if( isOrderDistinct ){
109377109394
orderDistinctMask |= pLoop->maskSelf;
@@ -109385,11 +109402,10 @@
109385109402
}
109386109403
}
109387109404
} /* End the loop over all WhereLoops from outer-most down to inner-most */
109388109405
if( obSat==obDone ) return 1;
109389109406
if( !isOrderDistinct ) return 0;
109390
- if( isLastLoop ) return 1;
109391109407
return -1;
109392109408
}
109393109409
109394109410
#ifdef WHERETRACE_ENABLED
109395109411
/* For debugging use only: */
@@ -109492,11 +109508,11 @@
109492109508
rCost = whereCostAdd(rCost, pFrom->rCost);
109493109509
maskNew = pFrom->maskLoop | pWLoop->maskSelf;
109494109510
if( !isOrderedValid ){
109495109511
switch( wherePathSatisfiesOrderBy(pWInfo,
109496109512
pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags,
109497
- iLoop, iLoop==nLoop-1, pWLoop, &revMask) ){
109513
+ iLoop, pWLoop, &revMask) ){
109498109514
case 1: /* Yes. pFrom+pWLoop does satisfy the ORDER BY clause */
109499109515
isOrdered = 1;
109500109516
isOrderedValid = 1;
109501109517
break;
109502109518
case 0: /* No. pFrom+pWLoop will require a separate sort */
@@ -109511,10 +109527,11 @@
109511109527
revMask = pFrom->revLoop;
109512109528
}
109513109529
/* Check to see if pWLoop should be added to the mxChoice best so far */
109514109530
for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){
109515109531
if( pTo->maskLoop==maskNew && pTo->isOrderedValid==isOrderedValid ){
109532
+ testcase( jj==nTo-1 );
109516109533
break;
109517109534
}
109518109535
}
109519109536
if( jj>=nTo ){
109520109537
if( nTo>=mxChoice && rCost>=mxCost ){
@@ -109554,12 +109571,14 @@
109554109571
sqlite3DebugPrintf(" vs %s cost=%-3d order=%c\n",
109555109572
wherePathName(pTo, iLoop+1, 0), pTo->rCost,
109556109573
pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?');
109557109574
}
109558109575
#endif
109576
+ testcase( pTo->rCost==rCost );
109559109577
continue;
109560109578
}
109579
+ testcase( pTo->rCost==rCost+1 );
109561109580
/* A new and better score for a previously created equivalent path */
109562109581
#ifdef WHERETRACE_ENABLED
109563109582
if( sqlite3WhereTrace&0x4 ){
109564109583
sqlite3DebugPrintf(
109565109584
"Update %s cost=%-3d order=%c",
@@ -109618,13 +109637,16 @@
109618109637
return SQLITE_ERROR;
109619109638
}
109620109639
109621109640
/* Find the lowest cost path. pFrom will be left pointing to that path */
109622109641
pFrom = aFrom;
109642
+ assert( nFrom==1 );
109643
+#if 0 /* The following is needed if nFrom is ever more than 1 */
109623109644
for(ii=1; ii<nFrom; ii++){
109624109645
if( pFrom->rCost>aFrom[ii].rCost ) pFrom = &aFrom[ii];
109625109646
}
109647
+#endif
109626109648
assert( pWInfo->nLevel==nLoop );
109627109649
/* Load the lowest cost path into pWInfo */
109628109650
for(iLoop=0; iLoop<nLoop; iLoop++){
109629109651
WhereLevel *pLevel = pWInfo->a + iLoop;
109630109652
pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop];
@@ -109635,11 +109657,11 @@
109635109657
&& pWInfo->pDistinct
109636109658
&& nRowEst
109637109659
){
109638109660
Bitmask notUsed;
109639109661
int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinct, pFrom,
109640
- WHERE_DISTINCTBY, nLoop-1, 1, pFrom->aLoop[nLoop-1], &notUsed);
109662
+ WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed);
109641109663
if( rc==1 ) pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
109642109664
}
109643109665
if( pFrom->isOrdered ){
109644109666
if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
109645109667
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
@@ -110012,11 +110034,11 @@
110012110034
}
110013110035
}
110014110036
if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
110015110037
pWInfo->revMask = (Bitmask)(-1);
110016110038
}
110017
- if( pParse->nErr || db->mallocFailed ){
110039
+ if( pParse->nErr || NEVER(db->mallocFailed) ){
110018110040
goto whereBeginError;
110019110041
}
110020110042
#ifdef WHERETRACE_ENABLED
110021110043
if( sqlite3WhereTrace ){
110022110044
int ii;
@@ -110062,11 +110084,10 @@
110062110084
/* Open all tables in the pTabList and any indices selected for
110063110085
** searching those tables.
110064110086
*/
110065110087
sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
110066110088
notReady = ~(Bitmask)0;
110067
- pWInfo->nRowOut = (WhereCost)1;
110068110089
for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
110069110090
Table *pTab; /* Table to open */
110070110091
int iDb; /* Index of database containing table/index */
110071110092
struct SrcList_item *pTabItem;
110072110093
WhereLoop *pLoop;
@@ -110089,12 +110110,12 @@
110089110110
#endif
110090110111
if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
110091110112
&& (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
110092110113
int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
110093110114
sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
110094
- testcase( pTab->nCol==BMS-1 );
110095
- testcase( pTab->nCol==BMS );
110115
+ testcase( !pWInfo->okOnePass && pTab->nCol==BMS-1 );
110116
+ testcase( !pWInfo->okOnePass && pTab->nCol==BMS );
110096110117
if( !pWInfo->okOnePass && pTab->nCol<BMS ){
110097110118
Bitmask b = pTabItem->colUsed;
110098110119
int n = 0;
110099110120
for(; b; b=b>>1, n++){}
110100110121
sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1,
@@ -110231,16 +110252,14 @@
110231110252
if( (ws & WHERE_INDEXED)!=0 && (ws & (WHERE_IPK|WHERE_TEMP_INDEX))==0 ){
110232110253
sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
110233110254
}
110234110255
}
110235110256
110236
- /* If this scan uses an index, make code substitutions to read data
110237
- ** from the index in preference to the table. Sometimes, this means
110238
- ** the table need never be read from. This is a performance boost,
110239
- ** as the vdbe level waits until the table is read before actually
110240
- ** seeking the table cursor to the record corresponding to the current
110241
- ** position in the index.
110257
+ /* If this scan uses an index, make VDBE code substitutions to read data
110258
+ ** from the index instead of from the table where possible. In some cases
110259
+ ** this optimization prevents the table from ever being read, which can
110260
+ ** yield a significant performance boost.
110242110261
**
110243110262
** Calls to the code generator in between sqlite3WhereBegin and
110244110263
** sqlite3WhereEnd will have created code that references the table
110245110264
** directly. This loop scans all that code looking for opcodes
110246110265
** that reference the table and converts them into opcodes that
110247110266
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -670,11 +670,11 @@
670 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
671 ** [sqlite_version()] and [sqlite_source_id()].
672 */
673 #define SQLITE_VERSION "3.7.17"
674 #define SQLITE_VERSION_NUMBER 3007017
675 #define SQLITE_SOURCE_ID "2013-06-14 02:51:48 b920bb70bb009b7c54e7667544c9810c5ee25e19"
676
677 /*
678 ** CAPI3REF: Run-Time Library Version Numbers
679 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
680 **
@@ -76734,12 +76734,12 @@
76734 eType = IN_INDEX_EPH;
76735 if( prNotFound ){
76736 *prNotFound = rMayHaveNull = ++pParse->nMem;
76737 sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
76738 }else{
76739 testcase( pParse->nQueryLoop>1 );
76740 pParse->nQueryLoop = 1;
76741 if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){
76742 eType = IN_INDEX_ROWID;
76743 }
76744 }
76745 sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
@@ -97520,12 +97520,12 @@
97520 if( sqlite3ExprIsInteger(p->pLimit, &n) ){
97521 sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
97522 VdbeComment((v, "LIMIT counter"));
97523 if( n==0 ){
97524 sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
97525 }else{
97526 if( p->nSelectRow > n ) p->nSelectRow = n;
97527 }
97528 }else{
97529 sqlite3ExprCode(pParse, p->pLimit, iLimit);
97530 sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
97531 VdbeComment((v, "LIMIT counter"));
@@ -97715,11 +97715,11 @@
97715 pDelete = p->pPrior;
97716 p->pPrior = pPrior;
97717 p->nSelectRow += pPrior->nSelectRow;
97718 if( pPrior->pLimit
97719 && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
97720 && p->nSelectRow > nLimit
97721 ){
97722 p->nSelectRow = nLimit;
97723 }
97724 if( addr ){
97725 sqlite3VdbeJumpHere(v, addr);
@@ -100383,11 +100383,12 @@
100383 ** This might involve two separate loops with an OP_Sort in between, or
100384 ** it might be a single loop that uses an index to extract information
100385 ** in the right order to begin with.
100386 */
100387 sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
100388 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 0, 0);
 
100389 if( pWInfo==0 ) goto select_end;
100390 if( sqlite3WhereIsOrdered(pWInfo) ){
100391 /* The optimizer is able to deliver rows in group by order so
100392 ** we do not have to sort. The OP_OpenEphemeral table will be
100393 ** cancelled later because we still need to use the pKeyInfo
@@ -104352,11 +104353,11 @@
104352 ** useful utility to have around when working with this module.
104353 */
104354 typedef unsigned short int WhereCost;
104355
104356 /*
104357 ** This object contains information needed to implement a single nestd
104358 ** loop in WHERE clause.
104359 **
104360 ** Contrast this object with WhereLoop. This object describes the
104361 ** implementation of the loop. WhereLoop describes the algorithm.
104362 ** This object contains a pointer to the WhereLoop algorithm as one of
@@ -106328,11 +106329,10 @@
106328 int mxBitCol; /* Maximum column in pSrc->colUsed */
106329 CollSeq *pColl; /* Collating sequence to on a column */
106330 WhereLoop *pLoop; /* The Loop object */
106331 Bitmask idxCols; /* Bitmap of columns used for indexing */
106332 Bitmask extraCols; /* Bitmap of additional columns */
106333 const int mxConstraint = 10; /* Maximum number of constraints */
106334
106335 /* Generate code to skip over the creation and initialization of the
106336 ** transient index on 2nd and subsequent iterations of the loop. */
106337 v = pParse->pVdbe;
106338 assert( v!=0 );
@@ -106343,11 +106343,11 @@
106343 nColumn = 0;
106344 pTable = pSrc->pTab;
106345 pWCEnd = &pWC->a[pWC->nTerm];
106346 pLoop = pLevel->pWLoop;
106347 idxCols = 0;
106348 for(pTerm=pWC->a; pTerm<pWCEnd && pLoop->nLTerm<mxConstraint; pTerm++){
106349 if( termCanDriveIndex(pTerm, pSrc, notReady) ){
106350 int iCol = pTerm->u.leftColumn;
106351 Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
106352 testcase( iCol==BMS );
106353 testcase( iCol==BMS-1 );
@@ -106401,10 +106401,12 @@
106401 idxCols = 0;
106402 for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
106403 if( termCanDriveIndex(pTerm, pSrc, notReady) ){
106404 int iCol = pTerm->u.leftColumn;
106405 Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
 
 
106406 if( (idxCols & cMask)==0 ){
106407 Expr *pX = pTerm->pExpr;
106408 idxCols |= cMask;
106409 pIdx->aiColumn[n] = pTerm->u.leftColumn;
106410 pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
@@ -107214,12 +107216,10 @@
107214 ** string in this example would be set to SQLITE_AFF_NONE.
107215 */
107216 static int codeAllEqualityTerms(
107217 Parse *pParse, /* Parsing context */
107218 WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */
107219 WhereClause *pWC, /* The WHERE clause */
107220 Bitmask notReady, /* Which parts of FROM have not yet been coded */
107221 int bRev, /* Reverse the order of IN operators */
107222 int nExtraReg, /* Number of extra registers to allocate */
107223 char **pzAff /* OUT: Set to point to affinity string */
107224 ){
107225 int nEq; /* The number of == or IN constraints to code */
@@ -107335,11 +107335,10 @@
107335 int i, j;
107336 Column *aCol = pTab->aCol;
107337 int *aiColumn = pIndex->aiColumn;
107338 StrAccum txt;
107339
107340 if( pIndex==0 ) return 0;
107341 if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
107342 return 0;
107343 }
107344 sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
107345 txt.db = db;
@@ -107402,11 +107401,11 @@
107402
107403 if( pItem->zAlias ){
107404 zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
107405 }
107406 if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0
107407 && pLoop->u.btree.pIndex!=0
107408 ){
107409 char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
107410 zMsg = sqlite3MAppendf(db, zMsg, "%s USING %s%sINDEX%s%s%s", zMsg,
107411 ((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""),
107412 ((flags & WHERE_IDX_ONLY)?"COVERING ":""),
@@ -107422,11 +107421,11 @@
107422 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
107423 }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
107424 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
107425 }else if( flags&WHERE_BTM_LIMIT ){
107426 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
107427 }else if( flags&WHERE_TOP_LIMIT ){
107428 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
107429 }
107430 }
107431 #ifndef SQLITE_OMIT_VIRTUALTABLE
107432 else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
@@ -107593,10 +107592,11 @@
107593 assert( omitTable==0 );
107594 j = 0;
107595 pStart = pEnd = 0;
107596 if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++];
107597 if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++];
 
107598 if( bRev ){
107599 pTerm = pStart;
107600 pStart = pEnd;
107601 pEnd = pTerm;
107602 }
@@ -107647,15 +107647,11 @@
107647 }
107648 start = sqlite3VdbeCurrentAddr(v);
107649 pLevel->op = bRev ? OP_Prev : OP_Next;
107650 pLevel->p1 = iCur;
107651 pLevel->p2 = start;
107652 if( pStart==0 && pEnd==0 ){
107653 pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
107654 }else{
107655 assert( pLevel->p5==0 );
107656 }
107657 if( testOp!=OP_Noop ){
107658 iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
107659 sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
107660 sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
107661 sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
@@ -107762,13 +107758,11 @@
107762
107763 /* Generate code to evaluate all constraint terms using == or IN
107764 ** and store the values of those terms in an array of registers
107765 ** starting at regBase.
107766 */
107767 regBase = codeAllEqualityTerms(
107768 pParse, pLevel, pWC, notReady, bRev, nExtraReg, &zStartAff
107769 );
107770 zEndAff = sqlite3DbStrDup(pParse->db, zStartAff);
107771 addrNxt = pLevel->addrNxt;
107772
107773 /* If we are doing a reverse order scan on an ascending index, or
107774 ** a forward order scan on a descending index, interchange the
@@ -107778,14 +107772,14 @@
107778 || (bRev && pIdx->nColumn==nEq)
107779 ){
107780 SWAP(WhereTerm *, pRangeEnd, pRangeStart);
107781 }
107782
107783 testcase( pRangeStart && pRangeStart->eOperator & WO_LE );
107784 testcase( pRangeStart && pRangeStart->eOperator & WO_GE );
107785 testcase( pRangeEnd && pRangeEnd->eOperator & WO_LE );
107786 testcase( pRangeEnd && pRangeEnd->eOperator & WO_GE );
107787 startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
107788 endEq = !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
107789 start_constraints = pRangeStart || nEq>0;
107790
107791 /* Seek the index cursor to the start of the range. */
@@ -108088,12 +108082,12 @@
108088 ** terms, set pCov to the candidate covering index. Otherwise, set
108089 ** pCov to NULL to indicate that no candidate covering index will
108090 ** be available.
108091 */
108092 pSubLoop = pSubWInfo->a[0].pWLoop;
 
108093 if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0
108094 && (pSubLoop->wsFlags & WHERE_TEMP_INDEX)==0
108095 && (ii==0 || pSubLoop->u.btree.pIndex==pCov)
108096 ){
108097 assert( pSubWInfo->a[0].iIdxCur==iCovCur );
108098 pCov = pSubLoop->u.btree.pIndex;
108099 }else{
@@ -108180,10 +108174,12 @@
108180 assert( !ExprHasProperty(pE, EP_FromJoin) );
108181 assert( (pTerm->prereqRight & newNotReady)!=0 );
108182 pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
108183 if( pAlt==0 ) continue;
108184 if( pAlt->wtFlags & (TERM_CODED) ) continue;
 
 
108185 VdbeNoopComment((v, "begin transitive constraint"));
108186 sEq = *pAlt->pExpr;
108187 sEq.pLeft = pE->pLeft;
108188 sqlite3ExprIfFalse(pParse, &sEq, addrCont, SQLITE_JUMPIFNULL);
108189 }
@@ -108386,13 +108382,14 @@
108386 if( (p = pBuilder->pBest)!=0 ){
108387 if( p->maskSelf!=0 ){
108388 WhereCost rCost = whereCostAdd(p->rRun,p->rSetup);
108389 WhereCost rTemplate = whereCostAdd(pTemplate->rRun,pTemplate->rSetup);
108390 if( rCost < rTemplate ){
 
108391 goto whereLoopInsert_noop;
108392 }
108393 if( rCost == rTemplate && p->prereq <= pTemplate->prereq ){
108394 goto whereLoopInsert_noop;
108395 }
108396 }
108397 #if WHERETRACE_ENABLED
108398 if( sqlite3WhereTrace & 0x8 ){
@@ -108411,11 +108408,13 @@
108411 if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ) continue;
108412 if( (p->prereq & pTemplate->prereq)==p->prereq
108413 && p->rSetup<=pTemplate->rSetup
108414 && p->rRun<=pTemplate->rRun
108415 ){
108416 /* p is equal or better than pTemplate */
 
 
108417 if( p->nLTerm<pTemplate->nLTerm
108418 && (p->wsFlags & WHERE_INDEXED)!=0
108419 && (pTemplate->wsFlags & WHERE_INDEXED)!=0
108420 && p->u.btree.pIndex==pTemplate->u.btree.pIndex
108421 && p->prereq==pTemplate->prereq
@@ -108436,18 +108435,28 @@
108436 /* pTemplate is not helpful.
108437 ** Return without changing or adding anything */
108438 goto whereLoopInsert_noop;
108439 }
108440 }
 
 
 
108441 if( (p->prereq & pTemplate->prereq)==pTemplate->prereq
108442 && p->rSetup>=pTemplate->rSetup
108443 && p->rRun>=pTemplate->rRun
108444 ){
108445 /* Overwrite an existing WhereLoop with a better one */
 
 
 
 
108446 pNext = p->pNextLoop;
108447 break;
108448 }
 
 
 
108449 }
108450
108451 /* If we reach this point it means that either p[] should be overwritten
108452 ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
108453 ** WhereLoop and insert it.
@@ -108522,11 +108531,10 @@
108522
108523 pNew = pBuilder->pNew;
108524 if( db->mallocFailed ) return SQLITE_NOMEM;
108525
108526 assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
108527 assert( pNew->u.btree.nEq<=pProbe->nColumn );
108528 assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
108529 if( pNew->wsFlags & WHERE_BTM_LIMIT ){
108530 opMask = WO_LT|WO_LE;
108531 }else if( pProbe->tnum<=0 || (pSrc->jointype & JT_LEFT)!=0 ){
108532 opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
@@ -108533,10 +108541,11 @@
108533 }else{
108534 opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
108535 }
108536 if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
108537
 
108538 if( pNew->u.btree.nEq < pProbe->nColumn ){
108539 iCol = pProbe->aiColumn[pNew->u.btree.nEq];
108540 nRowEst = whereCost(pProbe->aiRowEst[pNew->u.btree.nEq+1]);
108541 }else{
108542 iCol = -1;
@@ -108580,11 +108589,11 @@
108580 pNew->wsFlags |= WHERE_COLUMN_EQ;
108581 if( iCol<0
108582 || (pProbe->onError!=OE_None && nInMul==0
108583 && pNew->u.btree.nEq==pProbe->nColumn-1)
108584 ){
108585 testcase( pNew->wsFlags & WHERE_COLUMN_IN );
108586 pNew->wsFlags |= WHERE_ONEROW;
108587 }
108588 pNew->u.btree.nEq++;
108589 pNew->nOut = nRowEst + nInMul;
108590 }else if( pTerm->eOperator & (WO_ISNULL) ){
@@ -108592,14 +108601,19 @@
108592 pNew->u.btree.nEq++;
108593 /* TUNING: IS NULL selects 2 rows */
108594 nIn = 10; assert( 10==whereCost(2) );
108595 pNew->nOut = nRowEst + nInMul + nIn;
108596 }else if( pTerm->eOperator & (WO_GT|WO_GE) ){
 
 
108597 pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
108598 pBtm = pTerm;
108599 pTop = 0;
108600 }else if( pTerm->eOperator & (WO_LT|WO_LE) ){
 
 
 
108601 pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT;
108602 pTop = pTerm;
108603 pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ?
108604 pNew->aLTerm[pNew->nLTerm-2] : 0;
108605 }
@@ -108612,10 +108626,12 @@
108612 }
108613 #ifdef SQLITE_ENABLE_STAT3
108614 if( pNew->u.btree.nEq==1 && pProbe->nSample ){
108615 tRowcnt nOut = 0;
108616 if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){
 
 
108617 rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut);
108618 }else if( (pTerm->eOperator & WO_IN)
108619 && !ExprHasProperty(pTerm->pExpr, EP_xIsSelect) ){
108620 rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut);
108621 }
@@ -108682,10 +108698,12 @@
108682 static Bitmask columnsInIndex(Index *pIdx){
108683 Bitmask m = 0;
108684 int j;
108685 for(j=pIdx->nColumn-1; j>=0; j--){
108686 int x = pIdx->aiColumn[j];
 
 
108687 if( x<BMS-1 ) m |= MASKBIT(x);
108688 }
108689 return m;
108690 }
108691
@@ -108855,12 +108873,11 @@
108855 /*
108856 ** Add all WhereLoop objects for a table of the join identified by
108857 ** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
108858 */
108859 static int whereLoopAddVirtual(
108860 WhereLoopBuilder *pBuilder, /* WHERE clause information */
108861 Bitmask mExtra /* Extra prerequesites for using this table */
108862 ){
108863 WhereInfo *pWInfo; /* WHERE analysis context */
108864 Parse *pParse; /* The parsing context */
108865 WhereClause *pWC; /* The WHERE clause */
108866 struct SrcList_item *pSrc; /* The FROM clause term to search */
@@ -108894,11 +108911,14 @@
108894 pNew->wsFlags = WHERE_VIRTUALTABLE;
108895 pNew->nLTerm = 0;
108896 pNew->u.vtab.needFree = 0;
108897 pUsage = pIdxInfo->aConstraintUsage;
108898 nConstraint = pIdxInfo->nConstraint;
108899 if( whereLoopResize(db, pNew, nConstraint) ) return SQLITE_NOMEM;
 
 
 
108900
108901 for(iPhase=0; iPhase<=3; iPhase++){
108902 if( !seenIn && (iPhase&1)!=0 ){
108903 iPhase++;
108904 if( iPhase>3 ) break;
@@ -108911,13 +108931,14 @@
108911 switch( iPhase ){
108912 case 0: /* Constants without IN operator */
108913 pIdxCons->usable = 0;
108914 if( (pTerm->eOperator & WO_IN)!=0 ){
108915 seenIn = 1;
108916 }else if( pTerm->prereqRight!=0 ){
 
108917 seenVar = 1;
108918 }else{
108919 pIdxCons->usable = 1;
108920 }
108921 break;
108922 case 1: /* Constants with IN operators */
108923 assert( seenIn );
@@ -108958,15 +108979,20 @@
108958 ){
108959 rc = SQLITE_ERROR;
108960 sqlite3ErrorMsg(pParse, "%s.xBestIndex() malfunction", pTab->zName);
108961 goto whereLoopAddVtab_exit;
108962 }
 
 
 
108963 pTerm = &pWC->a[j];
108964 pNew->prereq |= pTerm->prereqRight;
108965 assert( iTerm<pNew->nLSlot );
108966 pNew->aLTerm[iTerm] = pTerm;
108967 if( iTerm>mxTerm ) mxTerm = iTerm;
 
 
108968 if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<<iTerm;
108969 if( (pTerm->eOperator & WO_IN)!=0 ){
108970 if( pUsage[i].omit==0 ){
108971 /* Do not attempt to use an IN constraint if the virtual table
108972 ** says that the equivalent EQ constraint cannot be safely omitted.
@@ -109066,11 +109092,11 @@
109066 sBest.maskSelf = 0;
109067 sBest.rSetup = 0;
109068 sBest.rRun = 0;
109069 #ifndef SQLITE_OMIT_VIRTUALTABLE
109070 if( IsVirtual(pItem->pTab) ){
109071 rc = whereLoopAddVirtual(&sSubBuild, mExtra);
109072 }else
109073 #endif
109074 {
109075 rc = whereLoopAddBtree(&sSubBuild, mExtra);
109076 }
@@ -109123,11 +109149,11 @@
109123 if( ((pItem->jointype|priorJoinType) & (JT_LEFT|JT_CROSS))!=0 ){
109124 mExtra = mPrior;
109125 }
109126 priorJoinType = pItem->jointype;
109127 if( IsVirtual(pItem->pTab) ){
109128 rc = whereLoopAddVirtual(pBuilder, mExtra);
109129 }else{
109130 rc = whereLoopAddBtree(pBuilder, mExtra);
109131 }
109132 if( rc==SQLITE_OK ){
109133 rc = whereLoopAddOr(pBuilder, mExtra);
@@ -109153,11 +109179,10 @@
109153 WhereInfo *pWInfo, /* The WHERE clause */
109154 ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */
109155 WherePath *pPath, /* The WherePath to check */
109156 u16 wctrlFlags, /* Might contain WHERE_GROUPBY or WHERE_DISTINCTBY */
109157 u16 nLoop, /* Number of entries in pPath->aLoop[] */
109158 u8 isLastLoop, /* True if pLast is the inner-most loop */
109159 WhereLoop *pLast, /* Add this WhereLoop to the end of pPath->aLoop[] */
109160 Bitmask *pRevMask /* OUT: Mask of WhereLoops to run in reverse order */
109161 ){
109162 u8 revSet; /* True if rev is known */
109163 u8 rev; /* Composite sort order */
@@ -109214,10 +109239,11 @@
109214 return pLast->u.vtab.isOrdered;
109215 }
109216 if( nLoop && OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0;
109217
109218 nOrderBy = pOrderBy->nExpr;
 
109219 if( nOrderBy>BMS-1 ) return 0; /* Cannot optimize overly large ORDER BYs */
109220 isOrderDistinct = 1;
109221 obDone = MASKBIT(nOrderBy)-1;
109222 orderDistinctMask = 0;
109223 ready = 0;
@@ -109238,11 +109264,11 @@
109238 if( pOBExpr->op!=TK_COLUMN ) continue;
109239 if( pOBExpr->iTable!=iCur ) continue;
109240 pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
109241 ~ready, WO_EQ|WO_ISNULL, 0);
109242 if( pTerm==0 ) continue;
109243 if( pOBExpr->iColumn>=0 ){
109244 const char *z1, *z2;
109245 pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
109246 if( !pColl ) pColl = db->pDfltColl;
109247 z1 = pColl->zName;
109248 pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
@@ -109262,34 +109288,10 @@
109262 }else{
109263 nColumn = pIndex->nColumn;
109264 isOrderDistinct = pIndex->onError!=OE_None;
109265 }
109266
109267 /* For every term of the index that is constrained by == or IS NULL,
109268 ** mark off corresponding ORDER BY terms wherever they occur
109269 ** in the ORDER BY clause.
109270 */
109271 for(i=0; i<pLoop->u.btree.nEq; i++){
109272 pTerm = pLoop->aLTerm[i];
109273 if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))==0 ) continue;
109274 iColumn = pTerm->u.leftColumn;
109275 for(j=0; j<nOrderBy; j++){
109276 if( MASKBIT(j) & obSat ) continue;
109277 pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[j].pExpr);
109278 if( pOBExpr->op!=TK_COLUMN ) continue;
109279 if( pOBExpr->iTable!=iCur ) continue;
109280 if( pOBExpr->iColumn!=iColumn ) continue;
109281 if( iColumn>=0 ){
109282 pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[j].pExpr);
109283 if( !pColl ) pColl = db->pDfltColl;
109284 if( sqlite3StrICmp(pColl->zName, pIndex->azColl[i])!=0 ) continue;
109285 }
109286 obSat |= MASKBIT(j);
109287 }
109288 if( obSat==obDone ) return 1;
109289 }
109290
109291 /* Loop through all columns of the index and deal with the ones
109292 ** that are not constrained by == or IN.
109293 */
109294 rev = revSet = 0;
109295 distinctColumns = 0;
@@ -109298,11 +109300,14 @@
109298
109299 /* Skip over == and IS NULL terms */
109300 if( j<pLoop->u.btree.nEq
109301 && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
109302 ){
109303 if( i & WO_ISNULL ) isOrderDistinct = 0;
 
 
 
109304 continue;
109305 }
109306
109307 /* Get the column number in the table (iColumn) and sort order
109308 ** (revIdx) for the j-th column of the index.
@@ -109312,10 +109317,11 @@
109312 iColumn = pIndex->aiColumn[j];
109313 revIdx = pIndex->aSortOrder[j];
109314 if( iColumn==pIndex->pTable->iPKey ) iColumn = -1;
109315 }else{
109316 /* The ROWID column at the end */
 
109317 iColumn = -1;
109318 revIdx = 0;
109319 }
109320
109321 /* An unconstrained column that might be NULL means that this
@@ -109335,10 +109341,12 @@
109335 bOnce = 1;
109336 isMatch = 0;
109337 for(i=0; bOnce && i<nOrderBy; i++){
109338 if( MASKBIT(i) & obSat ) continue;
109339 pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
 
 
109340 if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
109341 if( pOBExpr->op!=TK_COLUMN ) continue;
109342 if( pOBExpr->iTable!=iCur ) continue;
109343 if( pOBExpr->iColumn!=iColumn ) continue;
109344 if( iColumn>=0 ){
@@ -109348,11 +109356,14 @@
109348 }
109349 isMatch = 1;
109350 break;
109351 }
109352 if( isMatch ){
109353 if( iColumn<0 ) distinctColumns = 1;
 
 
 
109354 obSat |= MASKBIT(i);
109355 if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
109356 /* Make sure the sort order is compatible in an ORDER BY clause.
109357 ** Sort order is irrelevant for a GROUP BY clause. */
109358 if( revSet ){
@@ -109363,15 +109374,21 @@
109363 revSet = 1;
109364 }
109365 }
109366 }else{
109367 /* No match found */
109368 if( j==0 || j<nColumn ) isOrderDistinct = 0;
 
 
 
109369 break;
109370 }
109371 } /* end Loop over all index columns */
109372 if( distinctColumns ) isOrderDistinct = 1;
 
 
 
109373 } /* end-if not one-row */
109374
109375 /* Mark off any other ORDER BY terms that reference pLoop */
109376 if( isOrderDistinct ){
109377 orderDistinctMask |= pLoop->maskSelf;
@@ -109385,11 +109402,10 @@
109385 }
109386 }
109387 } /* End the loop over all WhereLoops from outer-most down to inner-most */
109388 if( obSat==obDone ) return 1;
109389 if( !isOrderDistinct ) return 0;
109390 if( isLastLoop ) return 1;
109391 return -1;
109392 }
109393
109394 #ifdef WHERETRACE_ENABLED
109395 /* For debugging use only: */
@@ -109492,11 +109508,11 @@
109492 rCost = whereCostAdd(rCost, pFrom->rCost);
109493 maskNew = pFrom->maskLoop | pWLoop->maskSelf;
109494 if( !isOrderedValid ){
109495 switch( wherePathSatisfiesOrderBy(pWInfo,
109496 pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags,
109497 iLoop, iLoop==nLoop-1, pWLoop, &revMask) ){
109498 case 1: /* Yes. pFrom+pWLoop does satisfy the ORDER BY clause */
109499 isOrdered = 1;
109500 isOrderedValid = 1;
109501 break;
109502 case 0: /* No. pFrom+pWLoop will require a separate sort */
@@ -109511,10 +109527,11 @@
109511 revMask = pFrom->revLoop;
109512 }
109513 /* Check to see if pWLoop should be added to the mxChoice best so far */
109514 for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){
109515 if( pTo->maskLoop==maskNew && pTo->isOrderedValid==isOrderedValid ){
 
109516 break;
109517 }
109518 }
109519 if( jj>=nTo ){
109520 if( nTo>=mxChoice && rCost>=mxCost ){
@@ -109554,12 +109571,14 @@
109554 sqlite3DebugPrintf(" vs %s cost=%-3d order=%c\n",
109555 wherePathName(pTo, iLoop+1, 0), pTo->rCost,
109556 pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?');
109557 }
109558 #endif
 
109559 continue;
109560 }
 
109561 /* A new and better score for a previously created equivalent path */
109562 #ifdef WHERETRACE_ENABLED
109563 if( sqlite3WhereTrace&0x4 ){
109564 sqlite3DebugPrintf(
109565 "Update %s cost=%-3d order=%c",
@@ -109618,13 +109637,16 @@
109618 return SQLITE_ERROR;
109619 }
109620
109621 /* Find the lowest cost path. pFrom will be left pointing to that path */
109622 pFrom = aFrom;
 
 
109623 for(ii=1; ii<nFrom; ii++){
109624 if( pFrom->rCost>aFrom[ii].rCost ) pFrom = &aFrom[ii];
109625 }
 
109626 assert( pWInfo->nLevel==nLoop );
109627 /* Load the lowest cost path into pWInfo */
109628 for(iLoop=0; iLoop<nLoop; iLoop++){
109629 WhereLevel *pLevel = pWInfo->a + iLoop;
109630 pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop];
@@ -109635,11 +109657,11 @@
109635 && pWInfo->pDistinct
109636 && nRowEst
109637 ){
109638 Bitmask notUsed;
109639 int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinct, pFrom,
109640 WHERE_DISTINCTBY, nLoop-1, 1, pFrom->aLoop[nLoop-1], &notUsed);
109641 if( rc==1 ) pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
109642 }
109643 if( pFrom->isOrdered ){
109644 if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
109645 pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
@@ -110012,11 +110034,11 @@
110012 }
110013 }
110014 if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
110015 pWInfo->revMask = (Bitmask)(-1);
110016 }
110017 if( pParse->nErr || db->mallocFailed ){
110018 goto whereBeginError;
110019 }
110020 #ifdef WHERETRACE_ENABLED
110021 if( sqlite3WhereTrace ){
110022 int ii;
@@ -110062,11 +110084,10 @@
110062 /* Open all tables in the pTabList and any indices selected for
110063 ** searching those tables.
110064 */
110065 sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
110066 notReady = ~(Bitmask)0;
110067 pWInfo->nRowOut = (WhereCost)1;
110068 for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
110069 Table *pTab; /* Table to open */
110070 int iDb; /* Index of database containing table/index */
110071 struct SrcList_item *pTabItem;
110072 WhereLoop *pLoop;
@@ -110089,12 +110110,12 @@
110089 #endif
110090 if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
110091 && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
110092 int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
110093 sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
110094 testcase( pTab->nCol==BMS-1 );
110095 testcase( pTab->nCol==BMS );
110096 if( !pWInfo->okOnePass && pTab->nCol<BMS ){
110097 Bitmask b = pTabItem->colUsed;
110098 int n = 0;
110099 for(; b; b=b>>1, n++){}
110100 sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1,
@@ -110231,16 +110252,14 @@
110231 if( (ws & WHERE_INDEXED)!=0 && (ws & (WHERE_IPK|WHERE_TEMP_INDEX))==0 ){
110232 sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
110233 }
110234 }
110235
110236 /* If this scan uses an index, make code substitutions to read data
110237 ** from the index in preference to the table. Sometimes, this means
110238 ** the table need never be read from. This is a performance boost,
110239 ** as the vdbe level waits until the table is read before actually
110240 ** seeking the table cursor to the record corresponding to the current
110241 ** position in the index.
110242 **
110243 ** Calls to the code generator in between sqlite3WhereBegin and
110244 ** sqlite3WhereEnd will have created code that references the table
110245 ** directly. This loop scans all that code looking for opcodes
110246 ** that reference the table and converts them into opcodes that
110247
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -670,11 +670,11 @@
670 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
671 ** [sqlite_version()] and [sqlite_source_id()].
672 */
673 #define SQLITE_VERSION "3.7.17"
674 #define SQLITE_VERSION_NUMBER 3007017
675 #define SQLITE_SOURCE_ID "2013-06-18 01:52:41 4c6d58d75d51e1ce829aec214617c3a89e784a2d"
676
677 /*
678 ** CAPI3REF: Run-Time Library Version Numbers
679 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
680 **
@@ -76734,12 +76734,12 @@
76734 eType = IN_INDEX_EPH;
76735 if( prNotFound ){
76736 *prNotFound = rMayHaveNull = ++pParse->nMem;
76737 sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
76738 }else{
76739 testcase( pParse->nQueryLoop>0 );
76740 pParse->nQueryLoop = 0;
76741 if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){
76742 eType = IN_INDEX_ROWID;
76743 }
76744 }
76745 sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
@@ -97520,12 +97520,12 @@
97520 if( sqlite3ExprIsInteger(p->pLimit, &n) ){
97521 sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
97522 VdbeComment((v, "LIMIT counter"));
97523 if( n==0 ){
97524 sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
97525 }else if( n>=0 && p->nSelectRow>(u64)n ){
97526 p->nSelectRow = n;
97527 }
97528 }else{
97529 sqlite3ExprCode(pParse, p->pLimit, iLimit);
97530 sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
97531 VdbeComment((v, "LIMIT counter"));
@@ -97715,11 +97715,11 @@
97715 pDelete = p->pPrior;
97716 p->pPrior = pPrior;
97717 p->nSelectRow += pPrior->nSelectRow;
97718 if( pPrior->pLimit
97719 && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
97720 && nLimit>0 && p->nSelectRow > (u64)nLimit
97721 ){
97722 p->nSelectRow = nLimit;
97723 }
97724 if( addr ){
97725 sqlite3VdbeJumpHere(v, addr);
@@ -100383,11 +100383,12 @@
100383 ** This might involve two separate loops with an OP_Sort in between, or
100384 ** it might be a single loop that uses an index to extract information
100385 ** in the right order to begin with.
100386 */
100387 sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
100388 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0,
100389 WHERE_GROUPBY, 0);
100390 if( pWInfo==0 ) goto select_end;
100391 if( sqlite3WhereIsOrdered(pWInfo) ){
100392 /* The optimizer is able to deliver rows in group by order so
100393 ** we do not have to sort. The OP_OpenEphemeral table will be
100394 ** cancelled later because we still need to use the pKeyInfo
@@ -104352,11 +104353,11 @@
104353 ** useful utility to have around when working with this module.
104354 */
104355 typedef unsigned short int WhereCost;
104356
104357 /*
104358 ** This object contains information needed to implement a single nested
104359 ** loop in WHERE clause.
104360 **
104361 ** Contrast this object with WhereLoop. This object describes the
104362 ** implementation of the loop. WhereLoop describes the algorithm.
104363 ** This object contains a pointer to the WhereLoop algorithm as one of
@@ -106328,11 +106329,10 @@
106329 int mxBitCol; /* Maximum column in pSrc->colUsed */
106330 CollSeq *pColl; /* Collating sequence to on a column */
106331 WhereLoop *pLoop; /* The Loop object */
106332 Bitmask idxCols; /* Bitmap of columns used for indexing */
106333 Bitmask extraCols; /* Bitmap of additional columns */
 
106334
106335 /* Generate code to skip over the creation and initialization of the
106336 ** transient index on 2nd and subsequent iterations of the loop. */
106337 v = pParse->pVdbe;
106338 assert( v!=0 );
@@ -106343,11 +106343,11 @@
106343 nColumn = 0;
106344 pTable = pSrc->pTab;
106345 pWCEnd = &pWC->a[pWC->nTerm];
106346 pLoop = pLevel->pWLoop;
106347 idxCols = 0;
106348 for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
106349 if( termCanDriveIndex(pTerm, pSrc, notReady) ){
106350 int iCol = pTerm->u.leftColumn;
106351 Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
106352 testcase( iCol==BMS );
106353 testcase( iCol==BMS-1 );
@@ -106401,10 +106401,12 @@
106401 idxCols = 0;
106402 for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
106403 if( termCanDriveIndex(pTerm, pSrc, notReady) ){
106404 int iCol = pTerm->u.leftColumn;
106405 Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
106406 testcase( iCol==BMS-1 );
106407 testcase( iCol==BMS );
106408 if( (idxCols & cMask)==0 ){
106409 Expr *pX = pTerm->pExpr;
106410 idxCols |= cMask;
106411 pIdx->aiColumn[n] = pTerm->u.leftColumn;
106412 pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
@@ -107214,12 +107216,10 @@
107216 ** string in this example would be set to SQLITE_AFF_NONE.
107217 */
107218 static int codeAllEqualityTerms(
107219 Parse *pParse, /* Parsing context */
107220 WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */
 
 
107221 int bRev, /* Reverse the order of IN operators */
107222 int nExtraReg, /* Number of extra registers to allocate */
107223 char **pzAff /* OUT: Set to point to affinity string */
107224 ){
107225 int nEq; /* The number of == or IN constraints to code */
@@ -107335,11 +107335,10 @@
107335 int i, j;
107336 Column *aCol = pTab->aCol;
107337 int *aiColumn = pIndex->aiColumn;
107338 StrAccum txt;
107339
 
107340 if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
107341 return 0;
107342 }
107343 sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
107344 txt.db = db;
@@ -107402,11 +107401,11 @@
107401
107402 if( pItem->zAlias ){
107403 zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
107404 }
107405 if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0
107406 && ALWAYS(pLoop->u.btree.pIndex!=0)
107407 ){
107408 char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
107409 zMsg = sqlite3MAppendf(db, zMsg, "%s USING %s%sINDEX%s%s%s", zMsg,
107410 ((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""),
107411 ((flags & WHERE_IDX_ONLY)?"COVERING ":""),
@@ -107422,11 +107421,11 @@
107421 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
107422 }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
107423 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
107424 }else if( flags&WHERE_BTM_LIMIT ){
107425 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
107426 }else if( ALWAYS(flags&WHERE_TOP_LIMIT) ){
107427 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
107428 }
107429 }
107430 #ifndef SQLITE_OMIT_VIRTUALTABLE
107431 else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
@@ -107593,10 +107592,11 @@
107592 assert( omitTable==0 );
107593 j = 0;
107594 pStart = pEnd = 0;
107595 if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++];
107596 if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++];
107597 assert( pStart!=0 || pEnd!=0 );
107598 if( bRev ){
107599 pTerm = pStart;
107600 pStart = pEnd;
107601 pEnd = pTerm;
107602 }
@@ -107647,15 +107647,11 @@
107647 }
107648 start = sqlite3VdbeCurrentAddr(v);
107649 pLevel->op = bRev ? OP_Prev : OP_Next;
107650 pLevel->p1 = iCur;
107651 pLevel->p2 = start;
107652 assert( pLevel->p5==0 );
 
 
 
 
107653 if( testOp!=OP_Noop ){
107654 iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
107655 sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
107656 sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
107657 sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
@@ -107762,13 +107758,11 @@
107758
107759 /* Generate code to evaluate all constraint terms using == or IN
107760 ** and store the values of those terms in an array of registers
107761 ** starting at regBase.
107762 */
107763 regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
 
 
107764 zEndAff = sqlite3DbStrDup(pParse->db, zStartAff);
107765 addrNxt = pLevel->addrNxt;
107766
107767 /* If we are doing a reverse order scan on an ascending index, or
107768 ** a forward order scan on a descending index, interchange the
@@ -107778,14 +107772,14 @@
107772 || (bRev && pIdx->nColumn==nEq)
107773 ){
107774 SWAP(WhereTerm *, pRangeEnd, pRangeStart);
107775 }
107776
107777 testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
107778 testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 );
107779 testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 );
107780 testcase( pRangeEnd && (pRangeEnd->eOperator & WO_GE)!=0 );
107781 startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
107782 endEq = !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
107783 start_constraints = pRangeStart || nEq>0;
107784
107785 /* Seek the index cursor to the start of the range. */
@@ -108088,12 +108082,12 @@
108082 ** terms, set pCov to the candidate covering index. Otherwise, set
108083 ** pCov to NULL to indicate that no candidate covering index will
108084 ** be available.
108085 */
108086 pSubLoop = pSubWInfo->a[0].pWLoop;
108087 assert( (pSubLoop->wsFlags & WHERE_TEMP_INDEX)==0 );
108088 if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0
 
108089 && (ii==0 || pSubLoop->u.btree.pIndex==pCov)
108090 ){
108091 assert( pSubWInfo->a[0].iIdxCur==iCovCur );
108092 pCov = pSubLoop->u.btree.pIndex;
108093 }else{
@@ -108180,10 +108174,12 @@
108174 assert( !ExprHasProperty(pE, EP_FromJoin) );
108175 assert( (pTerm->prereqRight & newNotReady)!=0 );
108176 pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
108177 if( pAlt==0 ) continue;
108178 if( pAlt->wtFlags & (TERM_CODED) ) continue;
108179 testcase( pAlt->eOperator & WO_EQ );
108180 testcase( pAlt->eOperator & WO_IN );
108181 VdbeNoopComment((v, "begin transitive constraint"));
108182 sEq = *pAlt->pExpr;
108183 sEq.pLeft = pE->pLeft;
108184 sqlite3ExprIfFalse(pParse, &sEq, addrCont, SQLITE_JUMPIFNULL);
108185 }
@@ -108386,13 +108382,14 @@
108382 if( (p = pBuilder->pBest)!=0 ){
108383 if( p->maskSelf!=0 ){
108384 WhereCost rCost = whereCostAdd(p->rRun,p->rSetup);
108385 WhereCost rTemplate = whereCostAdd(pTemplate->rRun,pTemplate->rSetup);
108386 if( rCost < rTemplate ){
108387 testcase( rCost==rTemplate-1 );
108388 goto whereLoopInsert_noop;
108389 }
108390 if( rCost==rTemplate && (p->prereq & pTemplate->prereq)==p->prereq ){
108391 goto whereLoopInsert_noop;
108392 }
108393 }
108394 #if WHERETRACE_ENABLED
108395 if( sqlite3WhereTrace & 0x8 ){
@@ -108411,11 +108408,13 @@
108408 if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ) continue;
108409 if( (p->prereq & pTemplate->prereq)==p->prereq
108410 && p->rSetup<=pTemplate->rSetup
108411 && p->rRun<=pTemplate->rRun
108412 ){
108413 /* This branch taken when p is equal or better than pTemplate in
108414 ** all of (1) dependences (2) setup-cost, and (3) run-cost. */
108415 testcase( p->rRun==pTemplate->rRun );
108416 if( p->nLTerm<pTemplate->nLTerm
108417 && (p->wsFlags & WHERE_INDEXED)!=0
108418 && (pTemplate->wsFlags & WHERE_INDEXED)!=0
108419 && p->u.btree.pIndex==pTemplate->u.btree.pIndex
108420 && p->prereq==pTemplate->prereq
@@ -108436,18 +108435,28 @@
108435 /* pTemplate is not helpful.
108436 ** Return without changing or adding anything */
108437 goto whereLoopInsert_noop;
108438 }
108439 }
108440 testcase( (p->prereq & pTemplate->prereq)==p->prereq
108441 && p->rSetup<=pTemplate->rSetup
108442 && p->rRun==pTemplate->rRun+1 );
108443 if( (p->prereq & pTemplate->prereq)==pTemplate->prereq
108444 && p->rSetup>=pTemplate->rSetup
108445 && p->rRun>=pTemplate->rRun
108446 ){
108447 /* Overwrite an existing WhereLoop with a better one: one that is
108448 ** better at one of (1) dependences, (2) setup-cost, or (3) run-cost
108449 ** and is no worse in any of those categories. */
108450 testcase( p->rSetup==pTemplate->rSetup );
108451 testcase( p->rRun==pTemplate->rRun );
108452 pNext = p->pNextLoop;
108453 break;
108454 }
108455 testcase( (p->prereq & pTemplate->prereq)==pTemplate->prereq
108456 && p->rSetup>=pTemplate->rSetup
108457 && p->rRun==pTemplate->rRun-1 );
108458 }
108459
108460 /* If we reach this point it means that either p[] should be overwritten
108461 ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
108462 ** WhereLoop and insert it.
@@ -108522,11 +108531,10 @@
108531
108532 pNew = pBuilder->pNew;
108533 if( db->mallocFailed ) return SQLITE_NOMEM;
108534
108535 assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
 
108536 assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
108537 if( pNew->wsFlags & WHERE_BTM_LIMIT ){
108538 opMask = WO_LT|WO_LE;
108539 }else if( pProbe->tnum<=0 || (pSrc->jointype & JT_LEFT)!=0 ){
108540 opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
@@ -108533,10 +108541,11 @@
108541 }else{
108542 opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
108543 }
108544 if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
108545
108546 assert( pNew->u.btree.nEq<=pProbe->nColumn );
108547 if( pNew->u.btree.nEq < pProbe->nColumn ){
108548 iCol = pProbe->aiColumn[pNew->u.btree.nEq];
108549 nRowEst = whereCost(pProbe->aiRowEst[pNew->u.btree.nEq+1]);
108550 }else{
108551 iCol = -1;
@@ -108580,11 +108589,11 @@
108589 pNew->wsFlags |= WHERE_COLUMN_EQ;
108590 if( iCol<0
108591 || (pProbe->onError!=OE_None && nInMul==0
108592 && pNew->u.btree.nEq==pProbe->nColumn-1)
108593 ){
108594 assert( (pNew->wsFlags & WHERE_COLUMN_IN)==0 || iCol<0 );
108595 pNew->wsFlags |= WHERE_ONEROW;
108596 }
108597 pNew->u.btree.nEq++;
108598 pNew->nOut = nRowEst + nInMul;
108599 }else if( pTerm->eOperator & (WO_ISNULL) ){
@@ -108592,14 +108601,19 @@
108601 pNew->u.btree.nEq++;
108602 /* TUNING: IS NULL selects 2 rows */
108603 nIn = 10; assert( 10==whereCost(2) );
108604 pNew->nOut = nRowEst + nInMul + nIn;
108605 }else if( pTerm->eOperator & (WO_GT|WO_GE) ){
108606 testcase( pTerm->eOperator & WO_GT );
108607 testcase( pTerm->eOperator & WO_GE );
108608 pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
108609 pBtm = pTerm;
108610 pTop = 0;
108611 }else{
108612 assert( pTerm->eOperator & (WO_LT|WO_LE) );
108613 testcase( pTerm->eOperator & WO_LT );
108614 testcase( pTerm->eOperator & WO_LE );
108615 pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT;
108616 pTop = pTerm;
108617 pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ?
108618 pNew->aLTerm[pNew->nLTerm-2] : 0;
108619 }
@@ -108612,10 +108626,12 @@
108626 }
108627 #ifdef SQLITE_ENABLE_STAT3
108628 if( pNew->u.btree.nEq==1 && pProbe->nSample ){
108629 tRowcnt nOut = 0;
108630 if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){
108631 testcase( pTerm->eOperator & WO_EQ );
108632 testcase( pTerm->eOperator & WO_ISNULL );
108633 rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut);
108634 }else if( (pTerm->eOperator & WO_IN)
108635 && !ExprHasProperty(pTerm->pExpr, EP_xIsSelect) ){
108636 rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut);
108637 }
@@ -108682,10 +108698,12 @@
108698 static Bitmask columnsInIndex(Index *pIdx){
108699 Bitmask m = 0;
108700 int j;
108701 for(j=pIdx->nColumn-1; j>=0; j--){
108702 int x = pIdx->aiColumn[j];
108703 testcase( x==BMS-1 );
108704 testcase( x==BMS-2 );
108705 if( x<BMS-1 ) m |= MASKBIT(x);
108706 }
108707 return m;
108708 }
108709
@@ -108855,12 +108873,11 @@
108873 /*
108874 ** Add all WhereLoop objects for a table of the join identified by
108875 ** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
108876 */
108877 static int whereLoopAddVirtual(
108878 WhereLoopBuilder *pBuilder /* WHERE clause information */
 
108879 ){
108880 WhereInfo *pWInfo; /* WHERE analysis context */
108881 Parse *pParse; /* The parsing context */
108882 WhereClause *pWC; /* The WHERE clause */
108883 struct SrcList_item *pSrc; /* The FROM clause term to search */
@@ -108894,11 +108911,14 @@
108911 pNew->wsFlags = WHERE_VIRTUALTABLE;
108912 pNew->nLTerm = 0;
108913 pNew->u.vtab.needFree = 0;
108914 pUsage = pIdxInfo->aConstraintUsage;
108915 nConstraint = pIdxInfo->nConstraint;
108916 if( whereLoopResize(db, pNew, nConstraint) ){
108917 sqlite3DbFree(db, pIdxInfo);
108918 return SQLITE_NOMEM;
108919 }
108920
108921 for(iPhase=0; iPhase<=3; iPhase++){
108922 if( !seenIn && (iPhase&1)!=0 ){
108923 iPhase++;
108924 if( iPhase>3 ) break;
@@ -108911,13 +108931,14 @@
108931 switch( iPhase ){
108932 case 0: /* Constants without IN operator */
108933 pIdxCons->usable = 0;
108934 if( (pTerm->eOperator & WO_IN)!=0 ){
108935 seenIn = 1;
108936 }
108937 if( pTerm->prereqRight!=0 ){
108938 seenVar = 1;
108939 }else if( (pTerm->eOperator & WO_IN)==0 ){
108940 pIdxCons->usable = 1;
108941 }
108942 break;
108943 case 1: /* Constants with IN operators */
108944 assert( seenIn );
@@ -108958,15 +108979,20 @@
108979 ){
108980 rc = SQLITE_ERROR;
108981 sqlite3ErrorMsg(pParse, "%s.xBestIndex() malfunction", pTab->zName);
108982 goto whereLoopAddVtab_exit;
108983 }
108984 testcase( iTerm==nConstraint-1 );
108985 testcase( j==0 );
108986 testcase( j==pWC->nTerm-1 );
108987 pTerm = &pWC->a[j];
108988 pNew->prereq |= pTerm->prereqRight;
108989 assert( iTerm<pNew->nLSlot );
108990 pNew->aLTerm[iTerm] = pTerm;
108991 if( iTerm>mxTerm ) mxTerm = iTerm;
108992 testcase( iTerm==15 );
108993 testcase( iTerm==16 );
108994 if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<<iTerm;
108995 if( (pTerm->eOperator & WO_IN)!=0 ){
108996 if( pUsage[i].omit==0 ){
108997 /* Do not attempt to use an IN constraint if the virtual table
108998 ** says that the equivalent EQ constraint cannot be safely omitted.
@@ -109066,11 +109092,11 @@
109092 sBest.maskSelf = 0;
109093 sBest.rSetup = 0;
109094 sBest.rRun = 0;
109095 #ifndef SQLITE_OMIT_VIRTUALTABLE
109096 if( IsVirtual(pItem->pTab) ){
109097 rc = whereLoopAddVirtual(&sSubBuild);
109098 }else
109099 #endif
109100 {
109101 rc = whereLoopAddBtree(&sSubBuild, mExtra);
109102 }
@@ -109123,11 +109149,11 @@
109149 if( ((pItem->jointype|priorJoinType) & (JT_LEFT|JT_CROSS))!=0 ){
109150 mExtra = mPrior;
109151 }
109152 priorJoinType = pItem->jointype;
109153 if( IsVirtual(pItem->pTab) ){
109154 rc = whereLoopAddVirtual(pBuilder);
109155 }else{
109156 rc = whereLoopAddBtree(pBuilder, mExtra);
109157 }
109158 if( rc==SQLITE_OK ){
109159 rc = whereLoopAddOr(pBuilder, mExtra);
@@ -109153,11 +109179,10 @@
109179 WhereInfo *pWInfo, /* The WHERE clause */
109180 ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */
109181 WherePath *pPath, /* The WherePath to check */
109182 u16 wctrlFlags, /* Might contain WHERE_GROUPBY or WHERE_DISTINCTBY */
109183 u16 nLoop, /* Number of entries in pPath->aLoop[] */
 
109184 WhereLoop *pLast, /* Add this WhereLoop to the end of pPath->aLoop[] */
109185 Bitmask *pRevMask /* OUT: Mask of WhereLoops to run in reverse order */
109186 ){
109187 u8 revSet; /* True if rev is known */
109188 u8 rev; /* Composite sort order */
@@ -109214,10 +109239,11 @@
109239 return pLast->u.vtab.isOrdered;
109240 }
109241 if( nLoop && OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0;
109242
109243 nOrderBy = pOrderBy->nExpr;
109244 testcase( nOrderBy==BMS-1 );
109245 if( nOrderBy>BMS-1 ) return 0; /* Cannot optimize overly large ORDER BYs */
109246 isOrderDistinct = 1;
109247 obDone = MASKBIT(nOrderBy)-1;
109248 orderDistinctMask = 0;
109249 ready = 0;
@@ -109238,11 +109264,11 @@
109264 if( pOBExpr->op!=TK_COLUMN ) continue;
109265 if( pOBExpr->iTable!=iCur ) continue;
109266 pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
109267 ~ready, WO_EQ|WO_ISNULL, 0);
109268 if( pTerm==0 ) continue;
109269 if( (pTerm->eOperator&WO_EQ)!=0 && pOBExpr->iColumn>=0 ){
109270 const char *z1, *z2;
109271 pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
109272 if( !pColl ) pColl = db->pDfltColl;
109273 z1 = pColl->zName;
109274 pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
@@ -109262,34 +109288,10 @@
109288 }else{
109289 nColumn = pIndex->nColumn;
109290 isOrderDistinct = pIndex->onError!=OE_None;
109291 }
109292
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109293 /* Loop through all columns of the index and deal with the ones
109294 ** that are not constrained by == or IN.
109295 */
109296 rev = revSet = 0;
109297 distinctColumns = 0;
@@ -109298,11 +109300,14 @@
109300
109301 /* Skip over == and IS NULL terms */
109302 if( j<pLoop->u.btree.nEq
109303 && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
109304 ){
109305 if( i & WO_ISNULL ){
109306 testcase( isOrderDistinct );
109307 isOrderDistinct = 0;
109308 }
109309 continue;
109310 }
109311
109312 /* Get the column number in the table (iColumn) and sort order
109313 ** (revIdx) for the j-th column of the index.
@@ -109312,10 +109317,11 @@
109317 iColumn = pIndex->aiColumn[j];
109318 revIdx = pIndex->aSortOrder[j];
109319 if( iColumn==pIndex->pTable->iPKey ) iColumn = -1;
109320 }else{
109321 /* The ROWID column at the end */
109322 assert( j==nColumn );
109323 iColumn = -1;
109324 revIdx = 0;
109325 }
109326
109327 /* An unconstrained column that might be NULL means that this
@@ -109335,10 +109341,12 @@
109341 bOnce = 1;
109342 isMatch = 0;
109343 for(i=0; bOnce && i<nOrderBy; i++){
109344 if( MASKBIT(i) & obSat ) continue;
109345 pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
109346 testcase( wctrlFlags & WHERE_GROUPBY );
109347 testcase( wctrlFlags & WHERE_DISTINCTBY );
109348 if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
109349 if( pOBExpr->op!=TK_COLUMN ) continue;
109350 if( pOBExpr->iTable!=iCur ) continue;
109351 if( pOBExpr->iColumn!=iColumn ) continue;
109352 if( iColumn>=0 ){
@@ -109348,11 +109356,14 @@
109356 }
109357 isMatch = 1;
109358 break;
109359 }
109360 if( isMatch ){
109361 if( iColumn<0 ){
109362 testcase( distinctColumns==0 );
109363 distinctColumns = 1;
109364 }
109365 obSat |= MASKBIT(i);
109366 if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
109367 /* Make sure the sort order is compatible in an ORDER BY clause.
109368 ** Sort order is irrelevant for a GROUP BY clause. */
109369 if( revSet ){
@@ -109363,15 +109374,21 @@
109374 revSet = 1;
109375 }
109376 }
109377 }else{
109378 /* No match found */
109379 if( j==0 || j<nColumn ){
109380 testcase( isOrderDistinct!=0 );
109381 isOrderDistinct = 0;
109382 }
109383 break;
109384 }
109385 } /* end Loop over all index columns */
109386 if( distinctColumns ){
109387 testcase( isOrderDistinct==0 );
109388 isOrderDistinct = 1;
109389 }
109390 } /* end-if not one-row */
109391
109392 /* Mark off any other ORDER BY terms that reference pLoop */
109393 if( isOrderDistinct ){
109394 orderDistinctMask |= pLoop->maskSelf;
@@ -109385,11 +109402,10 @@
109402 }
109403 }
109404 } /* End the loop over all WhereLoops from outer-most down to inner-most */
109405 if( obSat==obDone ) return 1;
109406 if( !isOrderDistinct ) return 0;
 
109407 return -1;
109408 }
109409
109410 #ifdef WHERETRACE_ENABLED
109411 /* For debugging use only: */
@@ -109492,11 +109508,11 @@
109508 rCost = whereCostAdd(rCost, pFrom->rCost);
109509 maskNew = pFrom->maskLoop | pWLoop->maskSelf;
109510 if( !isOrderedValid ){
109511 switch( wherePathSatisfiesOrderBy(pWInfo,
109512 pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags,
109513 iLoop, pWLoop, &revMask) ){
109514 case 1: /* Yes. pFrom+pWLoop does satisfy the ORDER BY clause */
109515 isOrdered = 1;
109516 isOrderedValid = 1;
109517 break;
109518 case 0: /* No. pFrom+pWLoop will require a separate sort */
@@ -109511,10 +109527,11 @@
109527 revMask = pFrom->revLoop;
109528 }
109529 /* Check to see if pWLoop should be added to the mxChoice best so far */
109530 for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){
109531 if( pTo->maskLoop==maskNew && pTo->isOrderedValid==isOrderedValid ){
109532 testcase( jj==nTo-1 );
109533 break;
109534 }
109535 }
109536 if( jj>=nTo ){
109537 if( nTo>=mxChoice && rCost>=mxCost ){
@@ -109554,12 +109571,14 @@
109571 sqlite3DebugPrintf(" vs %s cost=%-3d order=%c\n",
109572 wherePathName(pTo, iLoop+1, 0), pTo->rCost,
109573 pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?');
109574 }
109575 #endif
109576 testcase( pTo->rCost==rCost );
109577 continue;
109578 }
109579 testcase( pTo->rCost==rCost+1 );
109580 /* A new and better score for a previously created equivalent path */
109581 #ifdef WHERETRACE_ENABLED
109582 if( sqlite3WhereTrace&0x4 ){
109583 sqlite3DebugPrintf(
109584 "Update %s cost=%-3d order=%c",
@@ -109618,13 +109637,16 @@
109637 return SQLITE_ERROR;
109638 }
109639
109640 /* Find the lowest cost path. pFrom will be left pointing to that path */
109641 pFrom = aFrom;
109642 assert( nFrom==1 );
109643 #if 0 /* The following is needed if nFrom is ever more than 1 */
109644 for(ii=1; ii<nFrom; ii++){
109645 if( pFrom->rCost>aFrom[ii].rCost ) pFrom = &aFrom[ii];
109646 }
109647 #endif
109648 assert( pWInfo->nLevel==nLoop );
109649 /* Load the lowest cost path into pWInfo */
109650 for(iLoop=0; iLoop<nLoop; iLoop++){
109651 WhereLevel *pLevel = pWInfo->a + iLoop;
109652 pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop];
@@ -109635,11 +109657,11 @@
109657 && pWInfo->pDistinct
109658 && nRowEst
109659 ){
109660 Bitmask notUsed;
109661 int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinct, pFrom,
109662 WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed);
109663 if( rc==1 ) pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
109664 }
109665 if( pFrom->isOrdered ){
109666 if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
109667 pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
@@ -110012,11 +110034,11 @@
110034 }
110035 }
110036 if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
110037 pWInfo->revMask = (Bitmask)(-1);
110038 }
110039 if( pParse->nErr || NEVER(db->mallocFailed) ){
110040 goto whereBeginError;
110041 }
110042 #ifdef WHERETRACE_ENABLED
110043 if( sqlite3WhereTrace ){
110044 int ii;
@@ -110062,11 +110084,10 @@
110084 /* Open all tables in the pTabList and any indices selected for
110085 ** searching those tables.
110086 */
110087 sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
110088 notReady = ~(Bitmask)0;
 
110089 for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
110090 Table *pTab; /* Table to open */
110091 int iDb; /* Index of database containing table/index */
110092 struct SrcList_item *pTabItem;
110093 WhereLoop *pLoop;
@@ -110089,12 +110110,12 @@
110110 #endif
110111 if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
110112 && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
110113 int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
110114 sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
110115 testcase( !pWInfo->okOnePass && pTab->nCol==BMS-1 );
110116 testcase( !pWInfo->okOnePass && pTab->nCol==BMS );
110117 if( !pWInfo->okOnePass && pTab->nCol<BMS ){
110118 Bitmask b = pTabItem->colUsed;
110119 int n = 0;
110120 for(; b; b=b>>1, n++){}
110121 sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1,
@@ -110231,16 +110252,14 @@
110252 if( (ws & WHERE_INDEXED)!=0 && (ws & (WHERE_IPK|WHERE_TEMP_INDEX))==0 ){
110253 sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
110254 }
110255 }
110256
110257 /* If this scan uses an index, make VDBE code substitutions to read data
110258 ** from the index instead of from the table where possible. In some cases
110259 ** this optimization prevents the table from ever being read, which can
110260 ** yield a significant performance boost.
 
 
110261 **
110262 ** Calls to the code generator in between sqlite3WhereBegin and
110263 ** sqlite3WhereEnd will have created code that references the table
110264 ** directly. This loop scans all that code looking for opcodes
110265 ** that reference the table and converts them into opcodes that
110266
+1 -1
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107107
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108108
** [sqlite_version()] and [sqlite_source_id()].
109109
*/
110110
#define SQLITE_VERSION "3.7.17"
111111
#define SQLITE_VERSION_NUMBER 3007017
112
-#define SQLITE_SOURCE_ID "2013-06-14 02:51:48 b920bb70bb009b7c54e7667544c9810c5ee25e19"
112
+#define SQLITE_SOURCE_ID "2013-06-18 01:52:41 4c6d58d75d51e1ce829aec214617c3a89e784a2d"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
118118
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.17"
111 #define SQLITE_VERSION_NUMBER 3007017
112 #define SQLITE_SOURCE_ID "2013-06-14 02:51:48 b920bb70bb009b7c54e7667544c9810c5ee25e19"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
118
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.17"
111 #define SQLITE_VERSION_NUMBER 3007017
112 #define SQLITE_SOURCE_ID "2013-06-18 01:52:41 4c6d58d75d51e1ce829aec214617c3a89e784a2d"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
118
+1 -1
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107107
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108108
** [sqlite_version()] and [sqlite_source_id()].
109109
*/
110110
#define SQLITE_VERSION "3.7.17"
111111
#define SQLITE_VERSION_NUMBER 3007017
112
-#define SQLITE_SOURCE_ID "2013-06-14 02:51:48 b920bb70bb009b7c54e7667544c9810c5ee25e19"
112
+#define SQLITE_SOURCE_ID "2013-06-18 01:52:41 4c6d58d75d51e1ce829aec214617c3a89e784a2d"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
118118
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.17"
111 #define SQLITE_VERSION_NUMBER 3007017
112 #define SQLITE_SOURCE_ID "2013-06-14 02:51:48 b920bb70bb009b7c54e7667544c9810c5ee25e19"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
118
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.17"
111 #define SQLITE_VERSION_NUMBER 3007017
112 #define SQLITE_SOURCE_ID "2013-06-18 01:52:41 4c6d58d75d51e1ce829aec214617c3a89e784a2d"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
118
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,8 +1,23 @@
11
<title>Change Log</title>
22
33
<h2>Changes For Version 1.26 (as yet unreleased)</h2>
4
+ * The argument to the --port option for the [/help?cmd=ui | fossil ui] and
5
+ [/help?cmd=server | fossil server] commands can take an IP address in addition
6
+ to the port number, causing Fossil to bind to just that one IP address.
7
+ * After prompting for a password, also ask if that password should be
8
+ remembered.
9
+ * Performance improvements to the diff engine.
10
+ * Fix the side-by-side diff engine to work better with multi-byte unicode text.
11
+ * Color-coding in the web-based annotation (blame) display. Fix the annotation
12
+ engine so that it is no longer confused by time-warps.
13
+ * The markdown formatter is now available by default and can be used for
14
+ tickets, wiki, and embedded documentation.
15
+ * Add subcommands "fossil bisect log" and "fossil bisect status" to the
16
+ [/help?cmd=bisect | fossil bisect] command, as well as other bisect enhancements.
17
+ * Enhanced defenses that prevent spiders from using excessive CPU and bandwidth.
18
+ * Consistent us of the -n or --dry-run command line options.
419
* Win32: Fossil now understands Cygwin paths containing one or more of
520
the characters <nowiki>"*:<>?|</nowiki>. Those are normally forbidden in
621
win32. This means that the win32 fossil.exe is better usable in a Cygwin
722
environment. See
823
[http://cygwin.com/cygwin-ug-net/using-specialnames.html#pathnames-specialchars].
@@ -12,11 +27,23 @@
1227
See
1328
[http://cygwin.com/cygwin-ug-net/using-specialnames.html#pathnames-casesensitive]
1429
* Enhancements to /timeline.rss, adding more flags for filtering
1530
results, including the ability to subscribe to changes made
1631
to individual tickets. For example: [/timeline.rss?y=t&tkt=12fceeec82].
32
+ * Improved handling of the differences between case-sensitive and
33
+ case-insensitive filesystems.
1734
* JSON API: added the 'status' command to report local checkout status.
35
+ * Fixes to the <tt>--args</tt> support and documented this feature in the help.
36
+ * Added [/stats_report] page.
37
+ * Added <tt>ym=YYYY-MM</tt> filter to the [/timeline?ym=2013-06].
38
+ * Fixed: <tt>config reset</tt> now re-installs default ticket report format.
39
+ * <tt>ssh://</tt> and <tt>file://</tt> protocols now ignore proxy settings.
40
+ * Added [/hash-color-test] web page.
41
+ * Cherry-pick merges are recorded internally (though no yet displayed on the
42
+ timeline graph.)
43
+ * Bring in the latest versions of SQLite, zlib, and autosetup from upstream.
44
+
1845
1946
<h2>Changes For Version 1.25 (2013-02-16)</h2>
2047
* Enhancements to ticket processing. There are now two tables: TICKET and
2148
TICKETCHNG. There is one row in TICKETCHNG for each ticket artifact.
2249
Fields from ticket artifacts go into either or both of TICKET and
2350
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,8 +1,23 @@
1 <title>Change Log</title>
2
3 <h2>Changes For Version 1.26 (as yet unreleased)</h2>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4 * Win32: Fossil now understands Cygwin paths containing one or more of
5 the characters <nowiki>"*:<>?|</nowiki>. Those are normally forbidden in
6 win32. This means that the win32 fossil.exe is better usable in a Cygwin
7 environment. See
8 [http://cygwin.com/cygwin-ug-net/using-specialnames.html#pathnames-specialchars].
@@ -12,11 +27,23 @@
12 See
13 [http://cygwin.com/cygwin-ug-net/using-specialnames.html#pathnames-casesensitive]
14 * Enhancements to /timeline.rss, adding more flags for filtering
15 results, including the ability to subscribe to changes made
16 to individual tickets. For example: [/timeline.rss?y=t&tkt=12fceeec82].
 
 
17 * JSON API: added the 'status' command to report local checkout status.
 
 
 
 
 
 
 
 
 
 
18
19 <h2>Changes For Version 1.25 (2013-02-16)</h2>
20 * Enhancements to ticket processing. There are now two tables: TICKET and
21 TICKETCHNG. There is one row in TICKETCHNG for each ticket artifact.
22 Fields from ticket artifacts go into either or both of TICKET and
23
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,8 +1,23 @@
1 <title>Change Log</title>
2
3 <h2>Changes For Version 1.26 (as yet unreleased)</h2>
4 * The argument to the --port option for the [/help?cmd=ui | fossil ui] and
5 [/help?cmd=server | fossil server] commands can take an IP address in addition
6 to the port number, causing Fossil to bind to just that one IP address.
7 * After prompting for a password, also ask if that password should be
8 remembered.
9 * Performance improvements to the diff engine.
10 * Fix the side-by-side diff engine to work better with multi-byte unicode text.
11 * Color-coding in the web-based annotation (blame) display. Fix the annotation
12 engine so that it is no longer confused by time-warps.
13 * The markdown formatter is now available by default and can be used for
14 tickets, wiki, and embedded documentation.
15 * Add subcommands "fossil bisect log" and "fossil bisect status" to the
16 [/help?cmd=bisect | fossil bisect] command, as well as other bisect enhancements.
17 * Enhanced defenses that prevent spiders from using excessive CPU and bandwidth.
18 * Consistent us of the -n or --dry-run command line options.
19 * Win32: Fossil now understands Cygwin paths containing one or more of
20 the characters <nowiki>"*:<>?|</nowiki>. Those are normally forbidden in
21 win32. This means that the win32 fossil.exe is better usable in a Cygwin
22 environment. See
23 [http://cygwin.com/cygwin-ug-net/using-specialnames.html#pathnames-specialchars].
@@ -12,11 +27,23 @@
27 See
28 [http://cygwin.com/cygwin-ug-net/using-specialnames.html#pathnames-casesensitive]
29 * Enhancements to /timeline.rss, adding more flags for filtering
30 results, including the ability to subscribe to changes made
31 to individual tickets. For example: [/timeline.rss?y=t&tkt=12fceeec82].
32 * Improved handling of the differences between case-sensitive and
33 case-insensitive filesystems.
34 * JSON API: added the 'status' command to report local checkout status.
35 * Fixes to the <tt>--args</tt> support and documented this feature in the help.
36 * Added [/stats_report] page.
37 * Added <tt>ym=YYYY-MM</tt> filter to the [/timeline?ym=2013-06].
38 * Fixed: <tt>config reset</tt> now re-installs default ticket report format.
39 * <tt>ssh://</tt> and <tt>file://</tt> protocols now ignore proxy settings.
40 * Added [/hash-color-test] web page.
41 * Cherry-pick merges are recorded internally (though no yet displayed on the
42 timeline graph.)
43 * Bring in the latest versions of SQLite, zlib, and autosetup from upstream.
44
45
46 <h2>Changes For Version 1.25 (2013-02-16)</h2>
47 * Enhancements to ticket processing. There are now two tables: TICKET and
48 TICKETCHNG. There is one row in TICKETCHNG for each ticket artifact.
49 Fields from ticket artifacts go into either or both of TICKET and
50

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button