Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | More refactoring in where.c. (CVS 2552) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
a35bd50af8961133adc66e40c38402e8 |
User & Date: | drh 2005-07-19 22:22:13.000 |
Context
2005-07-20
| ||
14:31 | Extra memory usage instrumentation added. (CVS 2553) (check-in: ac669f56c0 user: drh tags: trunk) | |
2005-07-19
| ||
22:22 | More refactoring in where.c. (CVS 2552) (check-in: a35bd50af8 user: drh tags: trunk) | |
17:38 | Refactoring of the query optimizer in advance of adding better optimization. (CVS 2551) (check-in: 57c6bd3760 user: drh tags: trunk) | |
Changes
Changes to src/where.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** ** $Id: where.c,v 1.147 2005/07/19 22:22:13 drh Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8-1) |
︙ | ︙ | |||
546 547 548 549 550 551 552 553 554 555 556 557 558 559 | static void buildIndexProbe(Vdbe *v, int nColumn, int brk, Index *pIdx){ sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, brk); sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); sqlite3IndexAffinityStr(v, pIdx); } /* ** Generate code for an equality term of the WHERE clause. An equality ** term can be either X=expr or X IN (...). pTerm is the X. */ static void codeEqualityTerm( Parse *pParse, /* The parsing context */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 | static void buildIndexProbe(Vdbe *v, int nColumn, int brk, Index *pIdx){ sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, brk); sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); sqlite3IndexAffinityStr(v, pIdx); } /* ** Search for a term in the WHERE clause that is of the form "X <op> <expr>" ** where X is a reference to the iColumn of table iCur and <op> is either ** op1 or op2. Return a pointer to the term. */ static WhereTerm *findTerm( WhereClause *pWC, /* The WHERE clause to be searched */ int iCur, /* Cursor number of LHS */ int iColumn, /* Column number of LHS */ Bitmask loopMask, /* RHS must not overlap with this mask */ u8 op1, u8 op2 /* Expression must use either of these opcodes */ ){ WhereTerm *pTerm; int k; for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){ u8 op = pTerm->pExpr->op; if( pTerm->leftCursor==iCur && (pTerm->prereqRight & loopMask)==0 && pTerm->leftColumn==iColumn && (op==op1 || op==op2) ){ break; } } assert( k>0 ); /* The search is always successful */ return pTerm; } /* ** Generate code for an equality term of the WHERE clause. An equality ** term can be either X=expr or X IN (...). pTerm is the X. */ static void codeEqualityTerm( Parse *pParse, /* The parsing context */ |
︙ | ︙ | |||
1135 1136 1137 1138 1139 1140 1141 | int nColumn = (pLevel->score+16)/32; brk = pLevel->brk = sqlite3VdbeMakeLabel(v); /* For each column of the index, find the term of the WHERE clause that ** constraints that column. If the WHERE clause term is X=expr, then ** generate code to evaluate expr and leave the result on the stack */ for(j=0; j<nColumn; j++){ | < | | < < < < < < | < | < < < < | 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 | int nColumn = (pLevel->score+16)/32; brk = pLevel->brk = sqlite3VdbeMakeLabel(v); /* For each column of the index, find the term of the WHERE clause that ** constraints that column. If the WHERE clause term is X=expr, then ** generate code to evaluate expr and leave the result on the stack */ for(j=0; j<nColumn; j++){ pTerm = findTerm(&wc, iCur, pIdx->aiColumn[j], loopMask, TK_EQ, TK_IN); assert( pTerm!=0 ); assert( (pTerm->flags & TERM_CODED)==0 ); codeEqualityTerm(pParse, pTerm, brk, pLevel); } pLevel->iMem = pParse->nMem++; cont = pLevel->cont = sqlite3VdbeMakeLabel(v); buildIndexProbe(v, nColumn, brk, pIdx); sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0); /* Generate code (1) to move to the first matching element of the table. |
︙ | ︙ | |||
1283 1284 1285 1286 1287 1288 1289 | int start; int leFlag=0, geFlag=0; int testOp; /* Evaluate the equality constraints */ for(j=0; j<nEqColumn; j++){ | | < < | < < < < | | | < < < < | 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 | int start; int leFlag=0, geFlag=0; int testOp; /* Evaluate the equality constraints */ for(j=0; j<nEqColumn; j++){ pTerm = findTerm(&wc, iCur, pIdx->aiColumn[j], loopMask, TK_EQ, TK_EQ); assert( pTerm!=0 ); assert( (pTerm->flags & TERM_CODED)==0 ); sqlite3ExprCode(pParse, pTerm->pExpr->pRight); disableTerm(pLevel, pTerm); } /* Duplicate the equality term values because they will all be ** used twice: once to make the termination key and once to make the ** start key. */ for(j=0; j<nEqColumn; j++){ |
︙ | ︙ | |||
1321 1322 1323 1324 1325 1326 1327 | ** will end the search. There is no termination key if there ** are no equality terms and no "X<..." term. ** ** 2002-Dec-04: On a reverse-order scan, the so-called "termination" ** key computed here really ends up being the start key. */ if( (score & 4)!=0 ){ | < | > | | < < < < | | | | < < < < | 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 | ** will end the search. There is no termination key if there ** are no equality terms and no "X<..." term. ** ** 2002-Dec-04: On a reverse-order scan, the so-called "termination" ** key computed here really ends up being the start key. */ if( (score & 4)!=0 ){ Expr *pX; pTerm = findTerm(&wc, iCur, pIdx->aiColumn[j], loopMask, TK_LT, TK_LE); assert( pTerm!=0 ); pX = pTerm->pExpr; assert( (pTerm->flags & TERM_CODED)==0 ); sqlite3ExprCode(pParse, pX->pRight); leFlag = pX->op==TK_LE; disableTerm(pLevel, pTerm); testOp = OP_IdxGE; }else{ testOp = nEqColumn>0 ? OP_IdxGE : OP_Noop; leFlag = 1; } if( testOp!=OP_Noop ){ int nCol = nEqColumn + ((score & 4)!=0); |
︙ | ︙ | |||
1366 1367 1368 1369 1370 1371 1372 | ** that case, generate a "Rewind" instruction in place of the ** start key search. ** ** 2002-Dec-04: In the case of a reverse-order search, the so-called ** "start" key really ends up being used as the termination key. */ if( (score & 8)!=0 ){ | < | > | | < < < < | | | | < < < | 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 | ** that case, generate a "Rewind" instruction in place of the ** start key search. ** ** 2002-Dec-04: In the case of a reverse-order search, the so-called ** "start" key really ends up being used as the termination key. */ if( (score & 8)!=0 ){ Expr *pX; pTerm = findTerm(&wc, iCur, pIdx->aiColumn[j], loopMask, TK_GT, TK_GE); assert( pTerm!=0 ); pX = pTerm->pExpr; assert( (pTerm->flags & TERM_CODED)==0 ); sqlite3ExprCode(pParse, pX->pRight); geFlag = pX->op==TK_GE; disableTerm(pLevel, pTerm); }else{ geFlag = 1; } if( nEqColumn>0 || (score&8)!=0 ){ int nCol = nEqColumn + ((score&8)!=0); buildIndexProbe(v, nCol, brk, pIdx); if( pLevel->bRev ){ |
︙ | ︙ |