📄 where.c
字号:
/*** 2001 September 15**** The author disclaims copyright to this source code. In place of** a legal notice, here is a blessing:**** May you do good and not evil.** May you find forgiveness for yourself and forgive others.** May you share freely, never taking more than you give.***************************************************************************** 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.139 2005/06/12 21:35:53 drh Exp $*/#include "sqliteInt.h"/*** The query generator uses an array of instances of this structure to** help it analyze the subexpressions of the WHERE clause. Each WHERE** clause subexpression is separated from the others by an AND operator.**** The idxLeft and idxRight fields are the VDBE cursor numbers for the** table that contains the column that appears on the left-hand and** right-hand side of ExprInfo.p. If either side of ExprInfo.p is** something other than a simple column reference, then idxLeft or** idxRight are -1. **** It is the VDBE cursor number is the value stored in Expr.iTable** when Expr.op==TK_COLUMN and the value stored in SrcList.a[].iCursor.**** prereqLeft, prereqRight, and prereqAll record sets of cursor numbers,** but they do so indirectly. A single ExprMaskSet structure translates** cursor number into bits and the translated bit is stored in the prereq** fields. The translation is used in order to maximize the number of** bits that will fit in a Bitmask. The VDBE cursor numbers might be** spread out over the non-negative integers. For example, the cursor** numbers might be 3, 8, 9, 10, 20, 23, 41, and 45. The ExprMaskSet** translates these sparse cursor numbers into consecutive integers** beginning with 0 in order to make the best possible use of the available** bits in the Bitmask. So, in the example above, the cursor numbers** would be mapped into integers 0 through 7.**** prereqLeft tells us every VDBE cursor that is referenced on the** left-hand side of ExprInfo.p. prereqRight does the same for the** right-hand side of the expression. The following identity always** holds:**** prereqAll = prereqLeft | prereqRight**** The ExprInfo.indexable field is true if the ExprInfo.p expression** is of a form that might control an index. Indexable expressions** look like this:**** <column> <op> <expr>**** Where <column> is a simple column name and <op> is on of the operators** that allowedOp() recognizes. */typedef struct ExprInfo ExprInfo;struct ExprInfo { Expr *p; /* Pointer to the subexpression */ u8 indexable; /* True if this subexprssion is usable by an index */ short int idxLeft; /* p->pLeft is a column in this table number. -1 if ** p->pLeft is not the column of any table */ short int idxRight; /* p->pRight is a column in this table number. -1 if ** p->pRight is not the column of any table */ Bitmask prereqLeft; /* Bitmask of tables referenced by p->pLeft */ Bitmask prereqRight; /* Bitmask of tables referenced by p->pRight */ Bitmask prereqAll; /* Bitmask of tables referenced by p */};/*** An instance of the following structure keeps track of a mapping** between VDBE cursor numbers and bits of the bitmasks in ExprInfo.**** The VDBE cursor numbers are small integers contained in ** SrcList_item.iCursor and Expr.iTable fields. For any given WHERE ** clause, the cursor numbers might not begin with 0 and they might** contain gaps in the numbering sequence. But we want to make maximum** use of the bits in our bitmasks. This structure provides a mapping** from the sparse cursor numbers into consecutive integers beginning** with 0.**** If ExprMaskSet.ix[A]==B it means that The A-th bit of a Bitmask** corresponds VDBE cursor number B. The A-th bit of a bitmask is 1<<A.**** For example, if the WHERE clause expression used these VDBE** cursors: 4, 5, 8, 29, 57, 73. Then the ExprMaskSet structure** would map those cursor numbers into bits 0 through 5.**** Note that the mapping is not necessarily ordered. In the example** above, the mapping might go like this: 4->3, 5->1, 8->2, 29->0,** 57->5, 73->4. Or one of 719 other combinations might be used. It** does not really matter. What is important is that sparse cursor** numbers all get mapped into bit numbers that begin with 0 and contain** no gaps.*/typedef struct ExprMaskSet ExprMaskSet;struct ExprMaskSet { int n; /* Number of assigned cursor values */ int ix[sizeof(Bitmask)*8]; /* Cursor assigned to each bit */};/*** Determine the number of elements in an array.*/#define ARRAYSIZE(X) (sizeof(X)/sizeof(X[0]))/*** This routine identifies subexpressions in the WHERE clause where** each subexpression is separate by the AND operator. aSlot is ** filled with pointers to the subexpressions. For example:**** WHERE a=='hello' AND coalesce(b,11)<10 AND (c+12!=d OR c==22)** \________/ \_______________/ \________________/** slot[0] slot[1] slot[2]**** The original WHERE clause in pExpr is unaltered. All this routine** does is make aSlot[] entries point to substructure within pExpr.**** aSlot[] is an array of subexpressions structures. There are nSlot** spaces left in this array. This routine finds as many AND-separated** subexpressions as it can and puts pointers to those subexpressions** into aSlot[] entries. The return value is the number of slots filled.*/static int exprSplit(int nSlot, ExprInfo *aSlot, Expr *pExpr){ int cnt = 0; if( pExpr==0 || nSlot<1 ) return 0; if( nSlot==1 || pExpr->op!=TK_AND ){ aSlot[0].p = pExpr; return 1; } if( pExpr->pLeft->op!=TK_AND ){ aSlot[0].p = pExpr->pLeft; cnt = 1 + exprSplit(nSlot-1, &aSlot[1], pExpr->pRight); }else{ cnt = exprSplit(nSlot, aSlot, pExpr->pLeft); cnt += exprSplit(nSlot-cnt, &aSlot[cnt], pExpr->pRight); } return cnt;}/*** Initialize an expression mask set*/#define initMaskSet(P) memset(P, 0, sizeof(*P))/*** Return the bitmask for the given cursor number. Return 0 if** iCursor is not in the set.*/static Bitmask getMask(ExprMaskSet *pMaskSet, int iCursor){ int i; for(i=0; i<pMaskSet->n; i++){ if( pMaskSet->ix[i]==iCursor ){ return ((Bitmask)1)<<i; } } return 0;}/*** Create a new mask for cursor iCursor.*/static void createMask(ExprMaskSet *pMaskSet, int iCursor){ if( pMaskSet->n<ARRAYSIZE(pMaskSet->ix) ){ pMaskSet->ix[pMaskSet->n++] = iCursor; }}/*** Destroy an expression mask set*/#define freeMaskSet(P) /* NO-OP *//*** This routine walks (recursively) an expression tree and generates** a bitmask indicating which tables are used in that expression** tree.**** In order for this routine to work, the calling function must have** previously invoked sqlite3ExprResolveNames() on the expression. See** the header comment on that routine for additional information.** The sqlite3ExprResolveNames() routines looks for column names and** sets their opcodes to TK_COLUMN and their Expr.iTable fields to** the VDBE cursor number of the table.*/static Bitmask exprListTableUsage(ExprMaskSet *, ExprList *);static Bitmask exprTableUsage(ExprMaskSet *pMaskSet, Expr *p){ Bitmask mask = 0; if( p==0 ) return 0; if( p->op==TK_COLUMN ){ mask = getMask(pMaskSet, p->iTable); return mask; } mask = exprTableUsage(pMaskSet, p->pRight); mask |= exprTableUsage(pMaskSet, p->pLeft); mask |= exprListTableUsage(pMaskSet, p->pList); if( p->pSelect ){ Select *pS = p->pSelect; mask |= exprListTableUsage(pMaskSet, pS->pEList); mask |= exprListTableUsage(pMaskSet, pS->pGroupBy); mask |= exprListTableUsage(pMaskSet, pS->pOrderBy); mask |= exprTableUsage(pMaskSet, pS->pWhere); mask |= exprTableUsage(pMaskSet, pS->pHaving); } return mask;}static Bitmask exprListTableUsage(ExprMaskSet *pMaskSet, ExprList *pList){ int i; Bitmask mask = 0; if( pList ){ for(i=0; i<pList->nExpr; i++){ mask |= exprTableUsage(pMaskSet, pList->a[i].pExpr); } } return mask;}/*** Return TRUE if the given operator is one of the operators that is** allowed for an indexable WHERE clause term. The allowed operators are** "=", "<", ">", "<=", ">=", and "IN".*/static int allowedOp(int op){ assert( TK_GT==TK_LE-1 && TK_LE==TK_LT-1 && TK_LT==TK_GE-1 && TK_EQ==TK_GT-1); return op==TK_IN || (op>=TK_EQ && op<=TK_GE);}/*** Swap two objects of type T.*/#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}/*** Return the index in the SrcList that uses cursor iCur. If iCur is** used by the first entry in SrcList return 0. If iCur is used by** the second entry return 1. And so forth.**** SrcList is the set of tables in the FROM clause in the order that** they will be processed. The value returned here gives us an index** of which tables will be processed first.*/static int tableOrder(SrcList *pList, int iCur){ int i; struct SrcList_item *pItem; for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ if( pItem->iCursor==iCur ) return i; } return -1;}/*** The input to this routine is an ExprInfo structure with only the** "p" field filled in. The job of this routine is to analyze the** subexpression and populate all the other fields of the ExprInfo** structure.*/static void exprAnalyze(SrcList *pSrc, ExprMaskSet *pMaskSet, ExprInfo *pInfo){ Expr *pExpr = pInfo->p; pInfo->prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft); pInfo->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight); pInfo->prereqAll = exprTableUsage(pMaskSet, pExpr); pInfo->indexable = 0; pInfo->idxLeft = -1; pInfo->idxRight = -1; if( allowedOp(pExpr->op) && (pInfo->prereqRight & pInfo->prereqLeft)==0 ){ if( pExpr->pRight && pExpr->pRight->op==TK_COLUMN ){ pInfo->idxRight = pExpr->pRight->iTable; pInfo->indexable = 1; } if( pExpr->pLeft->op==TK_COLUMN ){ pInfo->idxLeft = pExpr->pLeft->iTable; pInfo->indexable = 1; } } if( pInfo->indexable ){ assert( pInfo->idxLeft!=pInfo->idxRight ); /* We want the expression to be of the form "X = expr", not "expr = X". ** So flip it over if necessary. If the expression is "X = Y", then ** we want Y to come from an earlier table than X. ** ** The collating sequence rule is to always choose the left expression. ** So if we do a flip, we also have to move the collating sequence. */ if( tableOrder(pSrc,pInfo->idxLeft)<tableOrder(pSrc,pInfo->idxRight) ){ assert( pExpr->op!=TK_IN ); SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl); SWAP(Expr*,pExpr->pRight,pExpr->pLeft); if( pExpr->op>=TK_GT ){ assert( TK_LT==TK_GT+2 ); assert( TK_GE==TK_LE+2 ); assert( TK_GT>TK_EQ ); assert( TK_GT<TK_LE ); assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE ); pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT; } SWAP(unsigned, pInfo->prereqLeft, pInfo->prereqRight); SWAP(short int, pInfo->idxLeft, pInfo->idxRight); } } }/*** This routine decides if pIdx can be used to satisfy the ORDER BY** clause. If it can, it returns 1. If pIdx cannot satisfy the** ORDER BY clause, this routine returns 0.**** pOrderBy is an ORDER BY clause from a SELECT statement. pTab is the** left-most table in the FROM clause of that same SELECT statement and** the table has a cursor number of "base". pIdx is an index on pTab.**** nEqCol is the number of columns of pIdx that are used as equality** constraints. Any of these columns may be missing from the ORDER BY** clause and the match can still be a success.**** If the index is UNIQUE, then the ORDER BY clause is allowed to have** additional terms past the end of the index and the match will still** be a success.**** All terms of the ORDER BY that match against the index must be either** ASC or DESC. (Terms of the ORDER BY clause past the end of a UNIQUE** index do not need to satisfy this constraint.) The *pbRev value is** set to 1 if the ORDER BY clause is all DESC and it is set to 0 if** the ORDER BY clause is all ASC.*/static int isSortingIndex( Parse *pParse, /* Parsing context */ Index *pIdx, /* The index we are testing */ Table *pTab, /* The table to be sorted */ int base, /* Cursor number for pTab */ ExprList *pOrderBy, /* The ORDER BY clause */ int nEqCol, /* Number of index columns with == constraints */ int *pbRev /* Set to 1 if ORDER BY is DESC */){ int i, j; /* Loop counters */ int sortOrder; /* Which direction we are sorting */ int nTerm; /* Number of ORDER BY terms */ struct ExprList_item *pTerm; /* A term of the ORDER BY clause */ sqlite3 *db = pParse->db; assert( pOrderBy!=0 ); nTerm = pOrderBy->nExpr; assert( nTerm>0 ); /* Match terms of the ORDER BY clause against columns of ** the index. */ for(i=j=0, pTerm=pOrderBy->a; j<nTerm && i<pIdx->nColumn; i++){ Expr *pExpr; /* The expression of the ORDER BY pTerm */ CollSeq *pColl; /* The collating sequence of pExpr */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -