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

📄 where.c

📁 sqlite最新源码
💻 C
📖 第 1 页 / 共 5 页
字号:
**    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 slot[] entries point to substructure within pExpr.**** In the previous sentence and in the diagram, "slot[]" refers to** the WhereClause.a[] array.  The slot[] array grows as needed to contain** all terms of the WHERE clause.*/static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){  pWC->op = (u8)op;  if( pExpr==0 ) return;  if( pExpr->op!=op ){    whereClauseInsert(pWC, pExpr, 0);  }else{    whereSplit(pWC, pExpr->pLeft, op);    whereSplit(pWC, pExpr->pRight, op);  }}/*** 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(WhereMaskSet *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.**** There is one cursor per table in the FROM clause.  The number of** tables in the FROM clause is limited by a test early in the** sqlite3WhereBegin() routine.  So we know that the pMaskSet->ix[]** array will never overflow.*/static void createMask(WhereMaskSet *pMaskSet, int iCursor){  assert( pMaskSet->n < ArraySize(pMaskSet->ix) );  pMaskSet->ix[pMaskSet->n++] = iCursor;}/*** 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 sqlite3ResolveExprNames() on the expression.  See** the header comment on that routine for additional information.** The sqlite3ResolveExprNames() 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.  This routine just has to** translate the cursor numbers into bitmask values and OR all** the bitmasks together.*/static Bitmask exprListTableUsage(WhereMaskSet*, ExprList*);static Bitmask exprSelectTableUsage(WhereMaskSet*, Select*);static Bitmask exprTableUsage(WhereMaskSet *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);  mask |= exprSelectTableUsage(pMaskSet, p->pSelect);  return mask;}static Bitmask exprListTableUsage(WhereMaskSet *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;}static Bitmask exprSelectTableUsage(WhereMaskSet *pMaskSet, Select *pS){  Bitmask mask = 0;  while( pS ){    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);    pS = pS->pPrior;  }  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_EQ && TK_GT<TK_GE );  assert( TK_LT>TK_EQ && TK_LT<TK_GE );  assert( TK_LE>TK_EQ && TK_LE<TK_GE );  assert( TK_GE==TK_EQ+4 );  return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;}/*** Swap two objects of type TYPE.*/#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}/*** Commute a comparison operator.  Expressions of the form "X op Y"** are converted into "Y op X".**** If a collation sequence is associated with either the left or right** side of the comparison, it remains associated with the same side after** the commutation. So "Y collate NOCASE op X" becomes ** "X collate NOCASE op Y". This is because any collation sequence on** the left hand side of a comparison overrides any collation sequence ** attached to the right. For the same reason the EP_ExpCollate flag** is not commuted.*/static void exprCommute(Parse *pParse, Expr *pExpr){  u16 expRight = (pExpr->pRight->flags & EP_ExpCollate);  u16 expLeft = (pExpr->pLeft->flags & EP_ExpCollate);  assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );  pExpr->pRight->pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);  pExpr->pLeft->pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);  SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl);  pExpr->pRight->flags = (pExpr->pRight->flags & ~EP_ExpCollate) | expLeft;  pExpr->pLeft->flags = (pExpr->pLeft->flags & ~EP_ExpCollate) | expRight;  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;  }}/*** Translate from TK_xx operator to WO_xx bitmask.*/static u16 operatorMask(int op){  u16 c;  assert( allowedOp(op) );  if( op==TK_IN ){    c = WO_IN;  }else if( op==TK_ISNULL ){    c = WO_ISNULL;  }else{    assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff );    c = (u16)(WO_EQ<<(op-TK_EQ));  }  assert( op!=TK_ISNULL || c==WO_ISNULL );  assert( op!=TK_IN || c==WO_IN );  assert( op!=TK_EQ || c==WO_EQ );  assert( op!=TK_LT || c==WO_LT );  assert( op!=TK_LE || c==WO_LE );  assert( op!=TK_GT || c==WO_GT );  assert( op!=TK_GE || c==WO_GE );  return c;}/*** 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 one of** the WO_xx operator codes specified by the op parameter.** Return a pointer to the term.  Return 0 if not found.*/static WhereTerm *findTerm(  WhereClause *pWC,     /* The WHERE clause to be searched */  int iCur,             /* Cursor number of LHS */  int iColumn,          /* Column number of LHS */  Bitmask notReady,     /* RHS must not overlap with this mask */  u32 op,               /* Mask of WO_xx values describing operator */  Index *pIdx           /* Must be compatible with this index, if not NULL */){  WhereTerm *pTerm;  int k;  assert( iCur>=0 );  op &= WO_ALL;  for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){    if( pTerm->leftCursor==iCur       && (pTerm->prereqRight & notReady)==0       && pTerm->u.leftColumn==iColumn       && (pTerm->eOperator & op)!=0    ){      if( pIdx && pTerm->eOperator!=WO_ISNULL ){        Expr *pX = pTerm->pExpr;        CollSeq *pColl;        char idxaff;        int j;        Parse *pParse = pWC->pParse;        idxaff = pIdx->pTable->aCol[iColumn].affinity;        if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue;        /* Figure out the collation sequence required from an index for        ** it to be useful for optimising expression pX. Store this        ** value in variable pColl.        */        assert(pX->pLeft);        pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);        assert(pColl || pParse->nErr);        for(j=0; pIdx->aiColumn[j]!=iColumn; j++){          if( NEVER(j>=pIdx->nColumn) ) return 0;        }        if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;      }      return pTerm;    }  }  return 0;}/* Forward reference */static void exprAnalyze(SrcList*, WhereClause*, int);/*** Call exprAnalyze on all terms in a WHERE clause.  *****/static void exprAnalyzeAll(  SrcList *pTabList,       /* the FROM clause */  WhereClause *pWC         /* the WHERE clause to be analyzed */){  int i;  for(i=pWC->nTerm-1; i>=0; i--){    exprAnalyze(pTabList, pWC, i);  }}#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION/*** Check to see if the given expression is a LIKE or GLOB operator that** can be optimized using inequality constraints.  Return TRUE if it is** so and false if not.**** In order for the operator to be optimizible, the RHS must be a string** literal that does not begin with a wildcard.  */static int isLikeOrGlob(  Parse *pParse,    /* Parsing and code generating context */  Expr *pExpr,      /* Test this expression */  int *pnPattern,   /* Number of non-wildcard prefix characters */  int *pisComplete, /* True if the only wildcard is % in the last character */  int *pnoCase      /* True if uppercase is equivalent to lowercase */){  const char *z;             /* String on RHS of LIKE operator */  Expr *pRight, *pLeft;      /* Right and left size of LIKE operator */  ExprList *pList;           /* List of operands to the LIKE operator */  int c;                     /* One character in z[] */  int cnt;                   /* Number of non-wildcard prefix characters */  char wc[3];                /* Wildcard characters */  CollSeq *pColl;            /* Collating sequence for LHS */  sqlite3 *db = pParse->db;  /* Database connection */  if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){    return 0;  }#ifdef SQLITE_EBCDIC  if( *pnoCase ) return 0;#endif  pList = pExpr->pList;  pRight = pList->a[0].pExpr;  if( pRight->op!=TK_STRING ){    return 0;  }  pLeft = pList->a[1].pExpr;  if( pLeft->op!=TK_COLUMN ){    return 0;  }  pColl = sqlite3ExprCollSeq(pParse, pLeft);  assert( pColl!=0 || pLeft->iColumn==-1 );  if( pColl==0 ){    /* No collation is defined for the ROWID.  Use the default. */    pColl = db->pDfltColl;  }  if( (pColl->type!=SQLITE_COLL_BINARY || *pnoCase) &&      (pColl->type!=SQLITE_COLL_NOCASE || !*pnoCase) ){    return 0;  }  sqlite3DequoteExpr(db, pRight);  z = (char *)pRight->token.z;  cnt = 0;  if( z ){    while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ cnt++; }  }  if( cnt==0 || 255==(u8)z[cnt-1] ){    return 0;  }  *pisComplete = z[cnt]==wc[0] && z[cnt+1]==0;  *pnPattern = cnt;  return 1;}#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */#ifndef SQLITE_OMIT_VIRTUALTABLE/*** Check to see if the given expression is of the form****         column MATCH expr**** If it is then return TRUE.  If not, return FALSE.*/static int isMatchOfColumn(  Expr *pExpr      /* Test this expression */){  ExprList *pList;  if( pExpr->op!=TK_FUNCTION ){    return 0;  }  if( pExpr->token.n!=5 ||       sqlite3StrNICmp((const char*)pExpr->token.z,"match",5)!=0 ){    return 0;  }  pList = pExpr->pList;  if( pList->nExpr!=2 ){    return 0;  }  if( pList->a[1].pExpr->op != TK_COLUMN ){    return 0;  }  return 1;}#endif /* SQLITE_OMIT_VIRTUALTABLE *//*** If the pBase expression originated in the ON or USING clause of** a join, then transfer the appropriate markings over to derived.*/static void transferJoinMarkings(Expr *pDerived, Expr *pBase){  pDerived->flags |= pBase->flags & EP_FromJoin;

⌨️ 快捷键说明

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