⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 where.c

📁 sqlite 嵌入式数据库的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    pExpr = pTerm->pExpr;    if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){      /* Can not use an index sort on anything that is not a column in the      ** left-most table of the FROM clause */      return 0;    }    pColl = sqlite3ExprCollSeq(pParse, pExpr);    if( !pColl ) pColl = db->pDfltColl;    if( pExpr->iColumn!=pIdx->aiColumn[i] || pColl!=pIdx->keyInfo.aColl[i] ){      /* Term j of the ORDER BY clause does not match column i of the index */      if( i<nEqCol ){        /* If an index column that is constrained by == fails to match an        ** ORDER BY term, that is OK.  Just ignore that column of the index        */        continue;      }else{        /* If an index column fails to match and is not constrained by ==        ** then the index cannot satisfy the ORDER BY constraint.        */        return 0;      }    }    if( i>nEqCol ){      if( pTerm->sortOrder!=sortOrder ){        /* Indices can only be used if all ORDER BY terms past the        ** equality constraints are all either DESC or ASC. */        return 0;      }    }else{      sortOrder = pTerm->sortOrder;    }    j++;    pTerm++;  }  /* The index can be used for sorting if all terms of the ORDER BY clause  ** or covered or if we ran out of index columns and the it is a UNIQUE  ** index.  */  if( j>=nTerm || (i>=pIdx->nColumn && pIdx->onError!=OE_None) ){    *pbRev = sortOrder==SQLITE_SO_DESC;    return 1;  }  return 0;}/*** Check table to see if the ORDER BY clause in pOrderBy can be satisfied** by sorting in order of ROWID.  Return true if so and set *pbRev to be** true for reverse ROWID and false for forward ROWID order.*/static int sortableByRowid(  int base,               /* Cursor number for table to be sorted */  ExprList *pOrderBy,     /* The ORDER BY clause */  int *pbRev              /* Set to 1 if ORDER BY is DESC */){  Expr *p;  assert( pOrderBy!=0 );  assert( pOrderBy->nExpr>0 );  p = pOrderBy->a[0].pExpr;  if( p->op==TK_COLUMN && p->iTable==base && p->iColumn==-1 ){    *pbRev = pOrderBy->a[0].sortOrder;    return 1;  }  return 0;}/*** Disable a term in the WHERE clause.  Except, do not disable the term** if it controls a LEFT OUTER JOIN and it did not originate in the ON** or USING clause of that join.**** Consider the term t2.z='ok' in the following queries:****   (1)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok'**   (2)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok'**   (3)  SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok'**** The t2.z='ok' is disabled in the in (2) because it originates** in the ON clause.  The term is disabled in (3) because it is not part** of a LEFT OUTER JOIN.  In (1), the term is not disabled.**** Disabling a term causes that term to not be tested in the inner loop** of the join.  Disabling is an optimization.  We would get the correct** results if nothing were ever disabled, but joins might run a little** slower.  The trick is to disable as much as we can without disabling** too much.  If we disabled in (1), we'd get the wrong answer.** See ticket #813.*/static void disableTerm(WhereLevel *pLevel, Expr **ppExpr){  Expr *pExpr = *ppExpr;  if( pLevel->iLeftJoin==0 || ExprHasProperty(pExpr, EP_FromJoin) ){    *ppExpr = 0;  }}/*** Generate code that builds a probe for an index.  Details:****    *  Check the top nColumn entries on the stack.  If any**       of those entries are NULL, jump immediately to brk,**       which is the loop exit, since no index entry will match**       if any part of the key is NULL.****    *  Construct a probe entry from the top nColumn entries in**       the stack with affinities appropriate for index pIdx.*/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 */  ExprInfo *pTerm,    /* The term of the WHERE clause to be coded */  int brk,            /* Jump here to abandon the loop */  WhereLevel *pLevel  /* When level of the FROM clause we are working on */){  Expr *pX = pTerm->p;  if( pX->op!=TK_IN ){    assert( pX->op==TK_EQ );    sqlite3ExprCode(pParse, pX->pRight);#ifndef SQLITE_OMIT_SUBQUERY  }else{    int iTab;    Vdbe *v = pParse->pVdbe;    sqlite3CodeSubselect(pParse, pX);    iTab = pX->iTable;    sqlite3VdbeAddOp(v, OP_Rewind, iTab, brk);    VdbeComment((v, "# %.*s", pX->span.n, pX->span.z));    pLevel->inP2 = sqlite3VdbeAddOp(v, OP_Column, iTab, 0);    pLevel->inOp = OP_Next;    pLevel->inP1 = iTab;#endif  }  disableTerm(pLevel, &pTerm->p);}/*** The number of bits in a Bitmask*/#define BMS  (sizeof(Bitmask)*8-1)/*** Generate the beginning of the loop used for WHERE clause processing.** The return value is a pointer to an opaque structure that contains** information needed to terminate the loop.  Later, the calling routine** should invoke sqlite3WhereEnd() with the return value of this function** in order to complete the WHERE clause processing.**** If an error occurs, this routine returns NULL.**** The basic idea is to do a nested loop, one loop for each table in** the FROM clause of a select.  (INSERT and UPDATE statements are the** same as a SELECT with only a single table in the FROM clause.)  For** example, if the SQL is this:****       SELECT * FROM t1, t2, t3 WHERE ...;**** Then the code generated is conceptually like the following:****      foreach row1 in t1 do       \    Code generated**        foreach row2 in t2 do      |-- by sqlite3WhereBegin()**          foreach row3 in t3 do   /**            ...**          end                     \    Code generated**        end                        |-- by sqlite3WhereEnd()**      end                         /**** There are Btree cursors associated with each table.  t1 uses cursor** number pTabList->a[0].iCursor.  t2 uses the cursor pTabList->a[1].iCursor.** And so forth.  This routine generates code to open those VDBE cursors** and sqlite3WhereEnd() generates the code to close them.**** The code that sqlite3WhereBegin() generates leaves the cursors named** in pTabList pointing at their appropriate entries.  The [...] code** can use OP_Column and OP_Rowid opcodes on these cursors to extract** data from the various tables of the loop.**** If the WHERE clause is empty, the foreach loops must each scan their** entire tables.  Thus a three-way join is an O(N^3) operation.  But if** the tables have indices and there are terms in the WHERE clause that** refer to those indices, a complete table scan can be avoided and the** code will run much faster.  Most of the work of this routine is checking** to see if there are indices that can be used to speed up the loop.**** Terms of the WHERE clause are also used to limit which rows actually** make it to the "..." in the middle of the loop.  After each "foreach",** terms of the WHERE clause that use only terms in that loop and outer** loops are evaluated and if false a jump is made around all subsequent** inner loops (or around the "..." if the test occurs within the inner-** most loop)**** OUTER JOINS**** An outer join of tables t1 and t2 is conceptally coded as follows:****    foreach row1 in t1 do**      flag = 0**      foreach row2 in t2 do**        start:**          ...**          flag = 1**      end**      if flag==0 then**        move the row2 cursor to a null row**        goto start**      fi**    end**** ORDER BY CLAUSE PROCESSING**** *ppOrderBy is a pointer to the ORDER BY clause of a SELECT statement,** if there is one.  If there is no ORDER BY clause or if this routine** is called from an UPDATE or DELETE statement, then ppOrderBy is NULL.**** If an index can be used so that the natural output order of the table** scan is correct for the ORDER BY clause, then that index is used and** *ppOrderBy is set to NULL.  This is an optimization that prevents an** unnecessary sort of the result set if an index appropriate for the** ORDER BY clause already exists.**** If the where clause loops cannot be arranged to provide the correct** output order, then the *ppOrderBy is unchanged.*/WhereInfo *sqlite3WhereBegin(  Parse *pParse,        /* The parser context */  SrcList *pTabList,    /* A list of all tables to be scanned */  Expr *pWhere,         /* The WHERE clause */  ExprList **ppOrderBy  /* An ORDER BY clause, or NULL */){  int i;                     /* Loop counter */  WhereInfo *pWInfo;         /* Will become the return value of this function */  Vdbe *v = pParse->pVdbe;   /* The virtual database engine */  int brk, cont = 0;         /* Addresses used during code generation */  int nExpr;           /* Number of subexpressions in the WHERE clause */  Bitmask loopMask;    /* One bit set for each outer loop */  ExprInfo *pTerm;     /* A single term in the WHERE clause; ptr to aExpr[] */  ExprMaskSet maskSet; /* The expression mask set */  int iDirectEq[BMS];  /* Term of the form ROWID==X for the N-th table */  int iDirectLt[BMS];  /* Term of the form ROWID<X or ROWID<=X */  int iDirectGt[BMS];  /* Term of the form ROWID>X or ROWID>=X */  ExprInfo aExpr[101]; /* The WHERE clause is divided into these terms */  struct SrcList_item *pTabItem;  /* A single entry from pTabList */  WhereLevel *pLevel;             /* A single level in the pWInfo list */  /* The number of terms in the FROM clause is limited by the number of  ** bits in a Bitmask   */  if( pTabList->nSrc>sizeof(Bitmask)*8 ){    sqlite3ErrorMsg(pParse, "at most %d tables in a join",       sizeof(Bitmask)*8);    return 0;  }  /* Split the WHERE clause into separate subexpressions where each  ** subexpression is separated by an AND operator.  If the aExpr[]  ** array fills up, the last entry might point to an expression which  ** contains additional unfactored AND operators.  */  initMaskSet(&maskSet);  memset(aExpr, 0, sizeof(aExpr));  nExpr = exprSplit(ARRAYSIZE(aExpr), aExpr, pWhere);  if( nExpr==ARRAYSIZE(aExpr) ){    sqlite3ErrorMsg(pParse, "WHERE clause too complex - no more "       "than %d terms allowed", (int)ARRAYSIZE(aExpr)-1);    return 0;  }      /* Allocate and initialize the WhereInfo structure that will become the  ** return value.  */  pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel));  if( sqlite3_malloc_failed ){    sqliteFree(pWInfo); /* Avoid leaking memory when malloc fails */    return 0;  }  pWInfo->pParse = pParse;  pWInfo->pTabList = pTabList;  pWInfo->iBreak = sqlite3VdbeMakeLabel(v);  /* Special case: a WHERE clause that is constant.  Evaluate the  ** expression and either jump over all of the code or fall thru.  */  if( pWhere && (pTabList->nSrc==0 || sqlite3ExprIsConstant(pWhere)) ){    sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, 1);    pWhere = 0;  }  /* Analyze all of the subexpressions.  */  for(i=0; i<pTabList->nSrc; i++){    createMask(&maskSet, pTabList->a[i].iCursor);  }  for(pTerm=aExpr, i=0; i<nExpr; i++, pTerm++){    exprAnalyze(pTabList, &maskSet, pTerm);  }  /* Figure out what index to use (if any) for each nested loop.  ** Make pWInfo->a[i].pIdx point to the index to use for the i-th nested  ** loop where i==0 is the outer loop and i==pTabList->nSrc-1 is the inner  ** loop.   **  ** If terms exist that use the ROWID of any table, then set the  ** iDirectEq[], iDirectLt[], or iDirectGt[] elements for that table  ** to the index of the term containing the ROWID.  We always prefer  ** to use a ROWID which can directly access a table rather than an  ** index which requires reading an index first to get the rowid then  ** doing a second read of the actual database table.  **  ** Actually, if there are more than 32 tables in the join, only the  ** first 32 tables are candidates for indices.  This is (again) due  ** to the limit of 32 bits in an integer bitmask.  */  loopMask = 0;  pTabItem = pTabList->a;  pLevel = pWInfo->a;  for(i=0; i<pTabList->nSrc && i<ARRAYSIZE(iDirectEq); i++,pTabItem++,pLevel++){    int j;    int iCur = pTabItem->iCursor;            /* The cursor for this table */    Bitmask mask = getMask(&maskSet, iCur);  /* Cursor mask for this table */    Table *pTab = pTabItem->pTab;    Index *pIdx;    Index *pBestIdx = 0;    int bestScore = 0;    int bestRev = 0;    /* Check to see if there is an expression that uses only the    ** ROWID field of this table.  For terms of the form ROWID==expr    ** set iDirectEq[i] to the index of the term.  For terms of the    ** form ROWID<expr or ROWID<=expr set iDirectLt[i] to the term index.    ** For terms like ROWID>expr or ROWID>=expr set iDirectGt[i].    **    ** (Added:) Treat ROWID IN expr like ROWID=expr.    */    pLevel->iIdxCur = -1;    iDirectEq[i] = -1;    iDirectLt[i] = -1;    iDirectGt[i] = -1;    for(pTerm=aExpr, j=0; j<nExpr; j++, pTerm++){      Expr *pX = pTerm->p;      if( pTerm->idxLeft==iCur && pX->pLeft->iColumn<0            && (pTerm->prereqRight & loopMask)==pTerm->prereqRight ){        switch( pX->op ){          case TK_IN:          case TK_EQ: iDirectEq[i] = j; break;          case TK_LE:          case TK_LT: iDirectLt[i] = j; break;          case TK_GE:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -