00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "sqliteInt.h"
00018
00019
00020
00021
00022
00023
00024 typedef struct ExprInfo ExprInfo;
00025 struct ExprInfo {
00026 Expr *p;
00027 u8 indexable;
00028 short int idxLeft;
00029
00030 short int idxRight;
00031
00032 unsigned prereqLeft;
00033 unsigned prereqRight;
00034 unsigned prereqAll;
00035 };
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 typedef struct ExprMaskSet ExprMaskSet;
00047 struct ExprMaskSet {
00048 int n;
00049 int ix[31];
00050 };
00051
00052
00053
00054
00055 #define ARRAYSIZE(X) (sizeof(X)/sizeof(X[0]))
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 static int exprSplit(int nSlot, ExprInfo *aSlot, Expr *pExpr){
00067 int cnt = 0;
00068 if( pExpr==0 || nSlot<1 ) return 0;
00069 if( nSlot==1 || pExpr->op!=TK_AND ){
00070 aSlot[0].p = pExpr;
00071 return 1;
00072 }
00073 if( pExpr->pLeft->op!=TK_AND ){
00074 aSlot[0].p = pExpr->pLeft;
00075 cnt = 1 + exprSplit(nSlot-1, &aSlot[1], pExpr->pRight);
00076 }else{
00077 cnt = exprSplit(nSlot, aSlot, pExpr->pLeft);
00078 cnt += exprSplit(nSlot-cnt, &aSlot[cnt], pExpr->pRight);
00079 }
00080 return cnt;
00081 }
00082
00083
00084
00085
00086 #define initMaskSet(P) memset(P, 0, sizeof(*P))
00087
00088
00089
00090
00091
00092 static int getMask(ExprMaskSet *pMaskSet, int iCursor){
00093 int i;
00094 for(i=0; i<pMaskSet->n; i++){
00095 if( pMaskSet->ix[i]==iCursor ) return 1<<i;
00096 }
00097 if( i==pMaskSet->n && i<ARRAYSIZE(pMaskSet->ix) ){
00098 pMaskSet->n++;
00099 pMaskSet->ix[i] = iCursor;
00100 return 1<<i;
00101 }
00102 return 0;
00103 }
00104
00105
00106
00107
00108 #define freeMaskSet(P)
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 static int exprTableUsage(ExprMaskSet *pMaskSet, Expr *p){
00123 unsigned int mask = 0;
00124 if( p==0 ) return 0;
00125 if( p->op==TK_COLUMN ){
00126 mask = getMask(pMaskSet, p->iTable);
00127 if( mask==0 ) mask = -1;
00128 return mask;
00129 }
00130 if( p->pRight ){
00131 mask = exprTableUsage(pMaskSet, p->pRight);
00132 }
00133 if( p->pLeft ){
00134 mask |= exprTableUsage(pMaskSet, p->pLeft);
00135 }
00136 if( p->pList ){
00137 int i;
00138 for(i=0; i<p->pList->nExpr; i++){
00139 mask |= exprTableUsage(pMaskSet, p->pList->a[i].pExpr);
00140 }
00141 }
00142 return mask;
00143 }
00144
00145
00146
00147
00148
00149
00150 static int allowedOp(int op){
00151 switch( op ){
00152 case TK_LT:
00153 case TK_LE:
00154 case TK_GT:
00155 case TK_GE:
00156 case TK_EQ:
00157 case TK_IN:
00158 return 1;
00159 default:
00160 return 0;
00161 }
00162 }
00163
00164
00165
00166
00167
00168
00169
00170 static void exprAnalyze(ExprMaskSet *pMaskSet, ExprInfo *pInfo){
00171 Expr *pExpr = pInfo->p;
00172 pInfo->prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
00173 pInfo->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
00174 pInfo->prereqAll = exprTableUsage(pMaskSet, pExpr);
00175 pInfo->indexable = 0;
00176 pInfo->idxLeft = -1;
00177 pInfo->idxRight = -1;
00178 if( allowedOp(pExpr->op) && (pInfo->prereqRight & pInfo->prereqLeft)==0 ){
00179 if( pExpr->pRight && pExpr->pRight->op==TK_COLUMN ){
00180 pInfo->idxRight = pExpr->pRight->iTable;
00181 pInfo->indexable = 1;
00182 }
00183 if( pExpr->pLeft->op==TK_COLUMN ){
00184 pInfo->idxLeft = pExpr->pLeft->iTable;
00185 pInfo->indexable = 1;
00186 }
00187 }
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 static Index *findSortingIndex(
00213 Table *pTab,
00214 int base,
00215 ExprList *pOrderBy,
00216 Index *pPreferredIdx,
00217 int nEqCol,
00218 int *pbRev
00219 ){
00220 int i, j;
00221 Index *pMatch;
00222 Index *pIdx;
00223 int sortOrder;
00224
00225 assert( pOrderBy!=0 );
00226 assert( pOrderBy->nExpr>0 );
00227 sortOrder = pOrderBy->a[0].sortOrder & SQLITE_SO_DIRMASK;
00228 for(i=0; i<pOrderBy->nExpr; i++){
00229 Expr *p;
00230 if( (pOrderBy->a[i].sortOrder & SQLITE_SO_DIRMASK)!=sortOrder ){
00231
00232
00233 return 0;
00234 }
00235 if( (pOrderBy->a[i].sortOrder & SQLITE_SO_TYPEMASK)!=SQLITE_SO_UNK ){
00236
00237 return 0;
00238 }
00239 p = pOrderBy->a[i].pExpr;
00240 if( p->op!=TK_COLUMN || p->iTable!=base ){
00241
00242
00243 return 0;
00244 }
00245 }
00246
00247
00248
00249
00250
00251 pMatch = 0;
00252 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
00253 int nExpr = pOrderBy->nExpr;
00254 if( pIdx->nColumn < nEqCol || pIdx->nColumn < nExpr ) continue;
00255 for(i=j=0; i<nEqCol; i++){
00256 if( pPreferredIdx->aiColumn[i]!=pIdx->aiColumn[i] ) break;
00257 if( j<nExpr && pOrderBy->a[j].pExpr->iColumn==pIdx->aiColumn[i] ){ j++; }
00258 }
00259 if( i<nEqCol ) continue;
00260 for(i=0; i+j<nExpr; i++){
00261 if( pOrderBy->a[i+j].pExpr->iColumn!=pIdx->aiColumn[i+nEqCol] ) break;
00262 }
00263 if( i+j>=nExpr ){
00264 pMatch = pIdx;
00265 if( pIdx==pPreferredIdx ) break;
00266 }
00267 }
00268 if( pMatch && pbRev ){
00269 *pbRev = sortOrder==SQLITE_SO_DESC;
00270 }
00271 return pMatch;
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 static void disableTerm(WhereLevel *pLevel, Expr **ppExpr){
00297 Expr *pExpr = *ppExpr;
00298 if( pLevel->iLeftJoin==0 || ExprHasProperty(pExpr, EP_FromJoin) ){
00299 *ppExpr = 0;
00300 }
00301 }
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 WhereInfo *sqliteWhereBegin(
00381 Parse *pParse,
00382 SrcList *pTabList,
00383 Expr *pWhere,
00384 int pushKey,
00385 ExprList **ppOrderBy
00386 ){
00387 int i;
00388 WhereInfo *pWInfo;
00389 Vdbe *v = pParse->pVdbe;
00390 int brk, cont = 0;
00391 int nExpr;
00392 int loopMask;
00393 int haveKey;
00394 ExprMaskSet maskSet;
00395 int iDirectEq[32];
00396 int iDirectLt[32];
00397 int iDirectGt[32];
00398 ExprInfo aExpr[101];
00399
00400
00401
00402
00403 assert( pushKey==0 || pTabList->nSrc==1 );
00404
00405
00406
00407
00408
00409
00410 initMaskSet(&maskSet);
00411 memset(aExpr, 0, sizeof(aExpr));
00412 nExpr = exprSplit(ARRAYSIZE(aExpr), aExpr, pWhere);
00413 if( nExpr==ARRAYSIZE(aExpr) ){
00414 sqliteErrorMsg(pParse, "WHERE clause too complex - no more "
00415 "than %d terms allowed", (int)ARRAYSIZE(aExpr)-1);
00416 return 0;
00417 }
00418
00419
00420
00421
00422 pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel));
00423 if( sqlite_malloc_failed ){
00424 sqliteFree(pWInfo);
00425 return 0;
00426 }
00427 pWInfo->pParse = pParse;
00428 pWInfo->pTabList = pTabList;
00429 pWInfo->peakNTab = pWInfo->savedNTab = pParse->nTab;
00430 pWInfo->iBreak = sqliteVdbeMakeLabel(v);
00431
00432
00433
00434
00435 if( pWhere && (pTabList->nSrc==0 || sqliteExprIsConstant(pWhere)) ){
00436 sqliteExprIfFalse(pParse, pWhere, pWInfo->iBreak, 1);
00437 pWhere = 0;
00438 }
00439
00440
00441
00442 for(i=0; i<nExpr; i++){
00443 exprAnalyze(&maskSet, &aExpr[i]);
00444
00445
00446
00447
00448 if( pParse->trigStack ){
00449 int x;
00450 if( (x = pParse->trigStack->newIdx) >= 0 ){
00451 int mask = ~getMask(&maskSet, x);
00452 aExpr[i].prereqRight &= mask;
00453 aExpr[i].prereqLeft &= mask;
00454 aExpr[i].prereqAll &= mask;
00455 }
00456 if( (x = pParse->trigStack->oldIdx) >= 0 ){
00457 int mask = ~getMask(&maskSet, x);
00458 aExpr[i].prereqRight &= mask;
00459 aExpr[i].prereqLeft &= mask;
00460 aExpr[i].prereqAll &= mask;
00461 }
00462 }
00463 }
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 loopMask = 0;
00482 for(i=0; i<pTabList->nSrc && i<ARRAYSIZE(iDirectEq); i++){
00483 int j;
00484 int iCur = pTabList->a[i].iCursor;
00485 int mask = getMask(&maskSet, iCur);
00486 Table *pTab = pTabList->a[i].pTab;
00487 Index *pIdx;
00488 Index *pBestIdx = 0;
00489 int bestScore = 0;
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 pWInfo->a[i].iCur = -1;
00500 iDirectEq[i] = -1;
00501 iDirectLt[i] = -1;
00502 iDirectGt[i] = -1;
00503 for(j=0; j<nExpr; j++){
00504 if( aExpr[j].idxLeft==iCur && aExpr[j].p->pLeft->iColumn<0
00505 && (aExpr[j].prereqRight & loopMask)==aExpr[j].prereqRight ){
00506 switch( aExpr[j].p->op ){
00507 case TK_IN:
00508 case TK_EQ: iDirectEq[i] = j; break;
00509 case TK_LE:
00510 case TK_LT: iDirectLt[i] = j; break;
00511 case TK_GE:
00512 case TK_GT: iDirectGt[i] = j; break;
00513 }
00514 }
00515 if( aExpr[j].idxRight==iCur && aExpr[j].p->pRight->iColumn<0
00516 && (aExpr[j].prereqLeft & loopMask)==aExpr[j].prereqLeft ){
00517 switch( aExpr[j].p->op ){
00518 case TK_EQ: iDirectEq[i] = j; break;
00519 case TK_LE:
00520 case TK_LT: iDirectGt[i] = j; break;
00521 case TK_GE:
00522 case TK_GT: iDirectLt[i] = j; break;
00523 }
00524 }
00525 }
00526 if( iDirectEq[i]>=0 ){
00527 loopMask |= mask;
00528 pWInfo->a[i].pIdx = 0;
00529 continue;
00530 }
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
00558 int eqMask = 0;
00559 int ltMask = 0;
00560 int gtMask = 0;
00561 int inMask = 0;
00562 int nEq, m, score;
00563
00564 if( pIdx->nColumn>32 ) continue;
00565 for(j=0; j<nExpr; j++){
00566 if( aExpr[j].idxLeft==iCur
00567 && (aExpr[j].prereqRight & loopMask)==aExpr[j].prereqRight ){
00568 int iColumn = aExpr[j].p->pLeft->iColumn;
00569 int k;
00570 for(k=0; k<pIdx->nColumn; k++){
00571 if( pIdx->aiColumn[k]==iColumn ){
00572 switch( aExpr[j].p->op ){
00573 case TK_IN: {
00574 if( k==0 ) inMask |= 1;
00575 break;
00576 }
00577 case TK_EQ: {
00578 eqMask |= 1<<k;
00579 break;
00580 }
00581 case TK_LE:
00582 case TK_LT: {
00583 ltMask |= 1<<k;
00584 break;
00585 }
00586 case TK_GE:
00587 case TK_GT: {
00588 gtMask |= 1<<k;
00589 break;
00590 }
00591 default: {
00592
00593 assert( 0 );
00594 break;
00595 }
00596 }
00597 break;
00598 }
00599 }
00600 }
00601 if( aExpr[j].idxRight==iCur
00602 && (aExpr[j].prereqLeft & loopMask)==aExpr[j].prereqLeft ){
00603 int iColumn = aExpr[j].p->pRight->iColumn;
00604 int k;
00605 for(k=0; k<pIdx->nColumn; k++){
00606 if( pIdx->aiColumn[k]==iColumn ){
00607 switch( aExpr[j].p->op ){
00608 case TK_EQ: {
00609 eqMask |= 1<<k;
00610 break;
00611 }
00612 case TK_LE:
00613 case TK_LT: {
00614 gtMask |= 1<<k;
00615 break;
00616 }
00617 case TK_GE:
00618 case TK_GT: {
00619 ltMask |= 1<<k;
00620 break;
00621 }
00622 default: {
00623
00624 assert( 0 );
00625 break;
00626 }
00627 }
00628 break;
00629 }
00630 }
00631 }
00632 }
00633
00634
00635
00636
00637 for(nEq=0; nEq<pIdx->nColumn; nEq++){
00638 m = (1<<(nEq+1))-1;
00639 if( (m & eqMask)!=m ) break;
00640 }
00641 score = nEq*8;
00642 m = 1<<nEq;
00643 if( m & ltMask ) score++;
00644 if( m & gtMask ) score+=2;
00645 if( score==0 && inMask ) score = 4;
00646 if( score>bestScore ){
00647 pBestIdx = pIdx;
00648 bestScore = score;
00649 }
00650 }
00651 pWInfo->a[i].pIdx = pBestIdx;
00652 pWInfo->a[i].score = bestScore;
00653 pWInfo->a[i].bRev = 0;
00654 loopMask |= mask;
00655 if( pBestIdx ){
00656 pWInfo->a[i].iCur = pParse->nTab++;
00657 pWInfo->peakNTab = pParse->nTab;
00658 }
00659 }
00660
00661
00662
00663
00664 if( ppOrderBy && *ppOrderBy && pTabList->nSrc>0 ){
00665 Index *pSortIdx;
00666 Index *pIdx;
00667 Table *pTab;
00668 int bRev = 0;
00669
00670 pTab = pTabList->a[0].pTab;
00671 pIdx = pWInfo->a[0].pIdx;
00672 if( pIdx && pWInfo->a[0].score==4 ){
00673
00674
00675
00676
00677 pSortIdx = 0;
00678 }else if( iDirectEq[0]>=0 || iDirectLt[0]>=0 || iDirectGt[0]>=0 ){
00679
00680
00681
00682 pSortIdx = 0;
00683 }else{
00684 int nEqCol = (pWInfo->a[0].score+4)/8;
00685 pSortIdx = findSortingIndex(pTab, pTabList->a[0].iCursor,
00686 *ppOrderBy, pIdx, nEqCol, &bRev);
00687 }
00688 if( pSortIdx && (pIdx==0 || pIdx==pSortIdx) ){
00689 if( pIdx==0 ){
00690 pWInfo->a[0].pIdx = pSortIdx;
00691 pWInfo->a[0].iCur = pParse->nTab++;
00692 pWInfo->peakNTab = pParse->nTab;
00693 }
00694 pWInfo->a[0].bRev = bRev;
00695 *ppOrderBy = 0;
00696 }
00697 }
00698
00699
00700
00701 for(i=0; i<pTabList->nSrc; i++){
00702 Table *pTab;
00703 Index *pIx;
00704
00705 pTab = pTabList->a[i].pTab;
00706 if( pTab->isTransient || pTab->pSelect ) continue;
00707 sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
00708 sqliteVdbeOp3(v, OP_OpenRead, pTabList->a[i].iCursor, pTab->tnum,
00709 pTab->zName, P3_STATIC);
00710 sqliteCodeVerifySchema(pParse, pTab->iDb);
00711 if( (pIx = pWInfo->a[i].pIdx)!=0 ){
00712 sqliteVdbeAddOp(v, OP_Integer, pIx->iDb, 0);
00713 sqliteVdbeOp3(v, OP_OpenRead, pWInfo->a[i].iCur, pIx->tnum, pIx->zName,0);
00714 }
00715 }
00716
00717
00718
00719 loopMask = 0;
00720 for(i=0; i<pTabList->nSrc; i++){
00721 int j, k;
00722 int iCur = pTabList->a[i].iCursor;
00723 Index *pIdx;
00724 WhereLevel *pLevel = &pWInfo->a[i];
00725
00726
00727
00728
00729
00730 if( i>0 && (pTabList->a[i-1].jointype & JT_LEFT)!=0 ){
00731 if( !pParse->nMem ) pParse->nMem++;
00732 pLevel->iLeftJoin = pParse->nMem++;
00733 sqliteVdbeAddOp(v, OP_String, 0, 0);
00734 sqliteVdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
00735 }
00736
00737 pIdx = pLevel->pIdx;
00738 pLevel->inOp = OP_Noop;
00739 if( i<ARRAYSIZE(iDirectEq) && iDirectEq[i]>=0 ){
00740
00741
00742
00743
00744
00745 k = iDirectEq[i];
00746 assert( k<nExpr );
00747 assert( aExpr[k].p!=0 );
00748 assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur );
00749 brk = pLevel->brk = sqliteVdbeMakeLabel(v);
00750 if( aExpr[k].idxLeft==iCur ){
00751 Expr *pX = aExpr[k].p;
00752 if( pX->op!=TK_IN ){
00753 sqliteExprCode(pParse, aExpr[k].p->pRight);
00754 }else if( pX->pList ){
00755 sqliteVdbeAddOp(v, OP_SetFirst, pX->iTable, brk);
00756 pLevel->inOp = OP_SetNext;
00757 pLevel->inP1 = pX->iTable;
00758 pLevel->inP2 = sqliteVdbeCurrentAddr(v);
00759 }else{
00760 assert( pX->pSelect );
00761 sqliteVdbeAddOp(v, OP_Rewind, pX->iTable, brk);
00762 sqliteVdbeAddOp(v, OP_KeyAsData, pX->iTable, 1);
00763 pLevel->inP2 = sqliteVdbeAddOp(v, OP_FullKey, pX->iTable, 0);
00764 pLevel->inOp = OP_Next;
00765 pLevel->inP1 = pX->iTable;
00766 }
00767 }else{
00768 sqliteExprCode(pParse, aExpr[k].p->pLeft);
00769 }
00770 disableTerm(pLevel, &aExpr[k].p);
00771 cont = pLevel->cont = sqliteVdbeMakeLabel(v);
00772 sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk);
00773 haveKey = 0;
00774 sqliteVdbeAddOp(v, OP_NotExists, iCur, brk);
00775 pLevel->op = OP_Noop;
00776 }else if( pIdx!=0 && pLevel->score>0 && pLevel->score%4==0 ){
00777
00778
00779
00780 int start;
00781 int testOp;
00782 int nColumn = (pLevel->score+4)/8;
00783 brk = pLevel->brk = sqliteVdbeMakeLabel(v);
00784 for(j=0; j<nColumn; j++){
00785 for(k=0; k<nExpr; k++){
00786 Expr *pX = aExpr[k].p;
00787 if( pX==0 ) continue;
00788 if( aExpr[k].idxLeft==iCur
00789 && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight
00790 && pX->pLeft->iColumn==pIdx->aiColumn[j]
00791 ){
00792 if( pX->op==TK_EQ ){
00793 sqliteExprCode(pParse, pX->pRight);
00794 disableTerm(pLevel, &aExpr[k].p);
00795 break;
00796 }
00797 if( pX->op==TK_IN && nColumn==1 ){
00798 if( pX->pList ){
00799 sqliteVdbeAddOp(v, OP_SetFirst, pX->iTable, brk);
00800 pLevel->inOp = OP_SetNext;
00801 pLevel->inP1 = pX->iTable;
00802 pLevel->inP2 = sqliteVdbeCurrentAddr(v);
00803 }else{
00804 assert( pX->pSelect );
00805 sqliteVdbeAddOp(v, OP_Rewind, pX->iTable, brk);
00806 sqliteVdbeAddOp(v, OP_KeyAsData, pX->iTable, 1);
00807 pLevel->inP2 = sqliteVdbeAddOp(v, OP_FullKey, pX->iTable, 0);
00808 pLevel->inOp = OP_Next;
00809 pLevel->inP1 = pX->iTable;
00810 }
00811 disableTerm(pLevel, &aExpr[k].p);
00812 break;
00813 }
00814 }
00815 if( aExpr[k].idxRight==iCur
00816 && aExpr[k].p->op==TK_EQ
00817 && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
00818 && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
00819 ){
00820 sqliteExprCode(pParse, aExpr[k].p->pLeft);
00821 disableTerm(pLevel, &aExpr[k].p);
00822 break;
00823 }
00824 }
00825 }
00826 pLevel->iMem = pParse->nMem++;
00827 cont = pLevel->cont = sqliteVdbeMakeLabel(v);
00828 sqliteVdbeAddOp(v, OP_NotNull, -nColumn, sqliteVdbeCurrentAddr(v)+3);
00829 sqliteVdbeAddOp(v, OP_Pop, nColumn, 0);
00830 sqliteVdbeAddOp(v, OP_Goto, 0, brk);
00831 sqliteVdbeAddOp(v, OP_MakeKey, nColumn, 0);
00832 sqliteAddIdxKeyType(v, pIdx);
00833 if( nColumn==pIdx->nColumn || pLevel->bRev ){
00834 sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
00835 testOp = OP_IdxGT;
00836 }else{
00837 sqliteVdbeAddOp(v, OP_Dup, 0, 0);
00838 sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
00839 sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
00840 testOp = OP_IdxGE;
00841 }
00842 if( pLevel->bRev ){
00843
00844 sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
00845 sqliteVdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk);
00846 start = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
00847 sqliteVdbeAddOp(v, OP_IdxLT, pLevel->iCur, brk);
00848 pLevel->op = OP_Prev;
00849 }else{
00850
00851 sqliteVdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk);
00852 start = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
00853 sqliteVdbeAddOp(v, testOp, pLevel->iCur, brk);
00854 pLevel->op = OP_Next;
00855 }
00856 sqliteVdbeAddOp(v, OP_RowKey, pLevel->iCur, 0);
00857 sqliteVdbeAddOp(v, OP_IdxIsNull, nColumn, cont);
00858 sqliteVdbeAddOp(v, OP_IdxRecno, pLevel->iCur, 0);
00859 if( i==pTabList->nSrc-1 && pushKey ){
00860 haveKey = 1;
00861 }else{
00862 sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
00863 haveKey = 0;
00864 }
00865 pLevel->p1 = pLevel->iCur;
00866 pLevel->p2 = start;
00867 }else if( i<ARRAYSIZE(iDirectLt) && (iDirectLt[i]>=0 || iDirectGt[i]>=0) ){
00868
00869
00870 int testOp = OP_Noop;
00871 int start;
00872
00873 brk = pLevel->brk = sqliteVdbeMakeLabel(v);
00874 cont = pLevel->cont = sqliteVdbeMakeLabel(v);
00875 if( iDirectGt[i]>=0 ){
00876 k = iDirectGt[i];
00877 assert( k<nExpr );
00878 assert( aExpr[k].p!=0 );
00879 assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur );
00880 if( aExpr[k].idxLeft==iCur ){
00881 sqliteExprCode(pParse, aExpr[k].p->pRight);
00882 }else{
00883 sqliteExprCode(pParse, aExpr[k].p->pLeft);
00884 }
00885 sqliteVdbeAddOp(v, OP_ForceInt,
00886 aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT, brk);
00887 sqliteVdbeAddOp(v, OP_MoveTo, iCur, brk);
00888 disableTerm(pLevel, &aExpr[k].p);
00889 }else{
00890 sqliteVdbeAddOp(v, OP_Rewind, iCur, brk);
00891 }
00892 if( iDirectLt[i]>=0 ){
00893 k = iDirectLt[i];
00894 assert( k<nExpr );
00895 assert( aExpr[k].p!=0 );
00896 assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur );
00897 if( aExpr[k].idxLeft==iCur ){
00898 sqliteExprCode(pParse, aExpr[k].p->pRight);
00899 }else{
00900 sqliteExprCode(pParse, aExpr[k].p->pLeft);
00901 }
00902
00903 pLevel->iMem = pParse->nMem++;
00904 sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
00905 if( aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT ){
00906 testOp = OP_Ge;
00907 }else{
00908 testOp = OP_Gt;
00909 }
00910 disableTerm(pLevel, &aExpr[k].p);
00911 }
00912 start = sqliteVdbeCurrentAddr(v);
00913 pLevel->op = OP_Next;
00914 pLevel->p1 = iCur;
00915 pLevel->p2 = start;
00916 if( testOp!=OP_Noop ){
00917 sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
00918 sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
00919 sqliteVdbeAddOp(v, testOp, 0, brk);
00920 }
00921 haveKey = 0;
00922 }else if( pIdx==0 ){
00923
00924
00925
00926 int start;
00927
00928 brk = pLevel->brk = sqliteVdbeMakeLabel(v);
00929 cont = pLevel->cont = sqliteVdbeMakeLabel(v);
00930 sqliteVdbeAddOp(v, OP_Rewind, iCur, brk);
00931 start = sqliteVdbeCurrentAddr(v);
00932 pLevel->op = OP_Next;
00933 pLevel->p1 = iCur;
00934 pLevel->p2 = start;
00935 haveKey = 0;
00936 }else{
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948 int score = pLevel->score;
00949 int nEqColumn = score/8;
00950 int start;
00951 int leFlag, geFlag;
00952 int testOp;
00953
00954
00955
00956 for(j=0; j<nEqColumn; j++){
00957 for(k=0; k<nExpr; k++){
00958 if( aExpr[k].p==0 ) continue;
00959 if( aExpr[k].idxLeft==iCur
00960 && aExpr[k].p->op==TK_EQ
00961 && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight
00962 && aExpr[k].p->pLeft->iColumn==pIdx->aiColumn[j]
00963 ){
00964 sqliteExprCode(pParse, aExpr[k].p->pRight);
00965 disableTerm(pLevel, &aExpr[k].p);
00966 break;
00967 }
00968 if( aExpr[k].idxRight==iCur
00969 && aExpr[k].p->op==TK_EQ
00970 && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
00971 && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
00972 ){
00973 sqliteExprCode(pParse, aExpr[k].p->pLeft);
00974 disableTerm(pLevel, &aExpr[k].p);
00975 break;
00976 }
00977 }
00978 }
00979
00980
00981
00982
00983
00984 for(j=0; j<nEqColumn; j++){
00985 sqliteVdbeAddOp(v, OP_Dup, nEqColumn-1, 0);
00986 }
00987
00988
00989
00990 cont = pLevel->cont = sqliteVdbeMakeLabel(v);
00991 brk = pLevel->brk = sqliteVdbeMakeLabel(v);
00992
00993
00994
00995
00996
00997
00998
00999
01000 if( (score & 1)!=0 ){
01001 for(k=0; k<nExpr; k++){
01002 Expr *pExpr = aExpr[k].p;
01003 if( pExpr==0 ) continue;
01004 if( aExpr[k].idxLeft==iCur
01005 && (pExpr->op==TK_LT || pExpr->op==TK_LE)
01006 && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight
01007 && pExpr->pLeft->iColumn==pIdx->aiColumn[j]
01008 ){
01009 sqliteExprCode(pParse, pExpr->pRight);
01010 leFlag = pExpr->op==TK_LE;
01011 disableTerm(pLevel, &aExpr[k].p);
01012 break;
01013 }
01014 if( aExpr[k].idxRight==iCur
01015 && (pExpr->op==TK_GT || pExpr->op==TK_GE)
01016 && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
01017 && pExpr->pRight->iColumn==pIdx->aiColumn[j]
01018 ){
01019 sqliteExprCode(pParse, pExpr->pLeft);
01020 leFlag = pExpr->op==TK_GE;
01021 disableTerm(pLevel, &aExpr[k].p);
01022 break;
01023 }
01024 }
01025 testOp = OP_IdxGE;
01026 }else{
01027 testOp = nEqColumn>0 ? OP_IdxGE : OP_Noop;
01028 leFlag = 1;
01029 }
01030 if( testOp!=OP_Noop ){
01031 int nCol = nEqColumn + (score & 1);
01032 pLevel->iMem = pParse->nMem++;
01033 sqliteVdbeAddOp(v, OP_NotNull, -nCol, sqliteVdbeCurrentAddr(v)+3);
01034 sqliteVdbeAddOp(v, OP_Pop, nCol, 0);
01035 sqliteVdbeAddOp(v, OP_Goto, 0, brk);
01036 sqliteVdbeAddOp(v, OP_MakeKey, nCol, 0);
01037 sqliteAddIdxKeyType(v, pIdx);
01038 if( leFlag ){
01039 sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
01040 }
01041 if( pLevel->bRev ){
01042 sqliteVdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk);
01043 }else{
01044 sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
01045 }
01046 }else if( pLevel->bRev ){
01047 sqliteVdbeAddOp(v, OP_Last, pLevel->iCur, brk);
01048 }
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059 if( (score & 2)!=0 ){
01060 for(k=0; k<nExpr; k++){
01061 Expr *pExpr = aExpr[k].p;
01062 if( pExpr==0 ) continue;
01063 if( aExpr[k].idxLeft==iCur
01064 && (pExpr->op==TK_GT || pExpr->op==TK_GE)
01065 && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight
01066 && pExpr->pLeft->iColumn==pIdx->aiColumn[j]
01067 ){
01068 sqliteExprCode(pParse, pExpr->pRight);
01069 geFlag = pExpr->op==TK_GE;
01070 disableTerm(pLevel, &aExpr[k].p);
01071 break;
01072 }
01073 if( aExpr[k].idxRight==iCur
01074 && (pExpr->op==TK_LT || pExpr->op==TK_LE)
01075 && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
01076 && pExpr->pRight->iColumn==pIdx->aiColumn[j]
01077 ){
01078 sqliteExprCode(pParse, pExpr->pLeft);
01079 geFlag = pExpr->op==TK_LE;
01080 disableTerm(pLevel, &aExpr[k].p);
01081 break;
01082 }
01083 }
01084 }else{
01085 geFlag = 1;
01086 }
01087 if( nEqColumn>0 || (score&2)!=0 ){
01088 int nCol = nEqColumn + ((score&2)!=0);
01089 sqliteVdbeAddOp(v, OP_NotNull, -nCol, sqliteVdbeCurrentAddr(v)+3);
01090 sqliteVdbeAddOp(v, OP_Pop, nCol, 0);
01091 sqliteVdbeAddOp(v, OP_Goto, 0, brk);
01092 sqliteVdbeAddOp(v, OP_MakeKey, nCol, 0);
01093 sqliteAddIdxKeyType(v, pIdx);
01094 if( !geFlag ){
01095 sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
01096 }
01097 if( pLevel->bRev ){
01098 pLevel->iMem = pParse->nMem++;
01099 sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
01100 testOp = OP_IdxLT;
01101 }else{
01102 sqliteVdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk);
01103 }
01104 }else if( pLevel->bRev ){
01105 testOp = OP_Noop;
01106 }else{
01107 sqliteVdbeAddOp(v, OP_Rewind, pLevel->iCur, brk);
01108 }
01109
01110
01111
01112
01113
01114 start = sqliteVdbeCurrentAddr(v);
01115 if( testOp!=OP_Noop ){
01116 sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
01117 sqliteVdbeAddOp(v, testOp, pLevel->iCur, brk);
01118 }
01119 sqliteVdbeAddOp(v, OP_RowKey, pLevel->iCur, 0);
01120 sqliteVdbeAddOp(v, OP_IdxIsNull, nEqColumn + (score & 1), cont);
01121 sqliteVdbeAddOp(v, OP_IdxRecno, pLevel->iCur, 0);
01122 if( i==pTabList->nSrc-1 && pushKey ){
01123 haveKey = 1;
01124 }else{
01125 sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
01126 haveKey = 0;
01127 }
01128
01129
01130
01131 pLevel->op = pLevel->bRev ? OP_Prev : OP_Next;
01132 pLevel->p1 = pLevel->iCur;
01133 pLevel->p2 = start;
01134 }
01135 loopMask |= getMask(&maskSet, iCur);
01136
01137
01138
01139
01140 for(j=0; j<nExpr; j++){
01141 if( aExpr[j].p==0 ) continue;
01142 if( (aExpr[j].prereqAll & loopMask)!=aExpr[j].prereqAll ) continue;
01143 if( pLevel->iLeftJoin && !ExprHasProperty(aExpr[j].p,EP_FromJoin) ){
01144 continue;
01145 }
01146 if( haveKey ){
01147 haveKey = 0;
01148 sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
01149 }
01150 sqliteExprIfFalse(pParse, aExpr[j].p, cont, 1);
01151 aExpr[j].p = 0;
01152 }
01153 brk = cont;
01154
01155
01156
01157
01158 if( pLevel->iLeftJoin ){
01159 pLevel->top = sqliteVdbeCurrentAddr(v);
01160 sqliteVdbeAddOp(v, OP_Integer, 1, 0);
01161 sqliteVdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
01162 for(j=0; j<nExpr; j++){
01163 if( aExpr[j].p==0 ) continue;
01164 if( (aExpr[j].prereqAll & loopMask)!=aExpr[j].prereqAll ) continue;
01165 if( haveKey ){
01166
01167
01168
01169
01170 haveKey = 0;
01171 sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
01172 }
01173 sqliteExprIfFalse(pParse, aExpr[j].p, cont, 1);
01174 aExpr[j].p = 0;
01175 }
01176 }
01177 }
01178 pWInfo->iContinue = cont;
01179 if( pushKey && !haveKey ){
01180 sqliteVdbeAddOp(v, OP_Recno, pTabList->a[0].iCursor, 0);
01181 }
01182 freeMaskSet(&maskSet);
01183 return pWInfo;
01184 }
01185
01186
01187
01188
01189
01190 void sqliteWhereEnd(WhereInfo *pWInfo){
01191 Vdbe *v = pWInfo->pParse->pVdbe;
01192 int i;
01193 WhereLevel *pLevel;
01194 SrcList *pTabList = pWInfo->pTabList;
01195
01196 for(i=pTabList->nSrc-1; i>=0; i--){
01197 pLevel = &pWInfo->a[i];
01198 sqliteVdbeResolveLabel(v, pLevel->cont);
01199 if( pLevel->op!=OP_Noop ){
01200 sqliteVdbeAddOp(v, pLevel->op, pLevel->p1, pLevel->p2);
01201 }
01202 sqliteVdbeResolveLabel(v, pLevel->brk);
01203 if( pLevel->inOp!=OP_Noop ){
01204 sqliteVdbeAddOp(v, pLevel->inOp, pLevel->inP1, pLevel->inP2);
01205 }
01206 if( pLevel->iLeftJoin ){
01207 int addr;
01208 addr = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iLeftJoin, 0);
01209 sqliteVdbeAddOp(v, OP_NotNull, 1, addr+4 + (pLevel->iCur>=0));
01210 sqliteVdbeAddOp(v, OP_NullRow, pTabList->a[i].iCursor, 0);
01211 if( pLevel->iCur>=0 ){
01212 sqliteVdbeAddOp(v, OP_NullRow, pLevel->iCur, 0);
01213 }
01214 sqliteVdbeAddOp(v, OP_Goto, 0, pLevel->top);
01215 }
01216 }
01217 sqliteVdbeResolveLabel(v, pWInfo->iBreak);
01218 for(i=0; i<pTabList->nSrc; i++){
01219 Table *pTab = pTabList->a[i].pTab;
01220 assert( pTab!=0 );
01221 if( pTab->isTransient || pTab->pSelect ) continue;
01222 pLevel = &pWInfo->a[i];
01223 sqliteVdbeAddOp(v, OP_Close, pTabList->a[i].iCursor, 0);
01224 if( pLevel->pIdx!=0 ){
01225 sqliteVdbeAddOp(v, OP_Close, pLevel->iCur, 0);
01226 }
01227 }
01228 #if 0
01229 if( pWInfo->pParse->nTab==pWInfo->peakNTab ){
01230 pWInfo->pParse->nTab = pWInfo->savedNTab;
01231 }
01232 #endif
01233 sqliteFree(pWInfo);
01234 return;
01235 }