亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? where.c

?? Trolltech公司發(fā)布的基于C++圖形開發(fā)環(huán)境
?? C
?? 第 1 頁 / 共 3 頁
字號:
/*** 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.**** $Id: qt/where.c   3.3.4   edited Mar 30 2004 $*/#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.*/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 */  unsigned prereqLeft;    /* Bitmask of tables referenced by p->pLeft */  unsigned prereqRight;   /* Bitmask of tables referenced by p->pRight */  unsigned prereqAll;     /* Bitmask of tables referenced by p */};/*** An instance of the following structure keeps track of a mapping** between VDBE cursor numbers and bitmasks.  The VDBE cursor numbers** are small integers contained in SrcList_item.iCursor and Expr.iTable** fields.  For any given WHERE clause, we want to track which cursors** are being used, so we assign a single bit in a 32-bit word to track** that cursor.  Then a 32-bit integer is able to show the set of all** cursors being used.*/typedef struct ExprMaskSet ExprMaskSet;struct ExprMaskSet {  int n;          /* Number of assigned cursor values */  int ix[32];     /* Cursor assigned to each bit */};/*** Determine the number of elements in an array.*/#define ARRAYSIZE(X)  (sizeof(X)/sizeof(X[0]))/*** This routine is used to divide the WHERE expression into subexpressions** separated by the AND operator.**** aSlot[] is an array of subexpressions structures.** There are nSlot spaces left in this array.  This routine attempts to** split pExpr into subexpressions and fills aSlot[] with those subexpressions.** 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.  Assign a new bitmask** if this is the first time the cursor has been seen.*/static int getMask(ExprMaskSet *pMaskSet, int iCursor){  int i;  for(i=0; i<pMaskSet->n; i++){    if( pMaskSet->ix[i]==iCursor ) return 1<<i;  }  if( i==pMaskSet->n && i<ARRAYSIZE(pMaskSet->ix) ){    pMaskSet->n++;    pMaskSet->ix[i] = iCursor;    return 1<<i;  }  return 0;}/*** 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 sqliteExprResolveIds() on the expression.  See** the header comment on that routine for additional information.** The sqliteExprResolveIds() 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 int exprTableUsage(ExprMaskSet *pMaskSet, Expr *p){  unsigned int mask = 0;  if( p==0 ) return 0;  if( p->op==TK_COLUMN ){    return getMask(pMaskSet, p->iTable);  }  if( p->pRight ){    mask = exprTableUsage(pMaskSet, p->pRight);  }  if( p->pLeft ){    mask |= exprTableUsage(pMaskSet, p->pLeft);  }  if( p->pList ){    int i;    for(i=0; i<p->pList->nExpr; i++){      mask |= exprTableUsage(pMaskSet, p->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.  The allowed operators are** "=", "<", ">", "<=", ">=", and "IN".*/static int allowedOp(int op){  switch( op ){    case TK_LT:    case TK_LE:    case TK_GT:    case TK_GE:    case TK_EQ:    case TK_IN:      return 1;    default:      return 0;  }}/*** 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(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;    }  }}/*** 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".**** This routine attempts to find an index for pTab that generates the** correct record sequence for the given ORDER BY clause.  The return value** is a pointer to an index that does the job.  NULL is returned if the** table has no index that will generate the correct sort order.**** If there are two or more indices that generate the correct sort order** and pPreferredIdx is one of those indices, then return pPreferredIdx.**** nEqCol is the number of columns of pPreferredIdx that are used as** equality constraints.  Any index returned must have exactly this same** set of columns.  The ORDER BY clause only matches index columns beyond the** the first nEqCol columns.**** All terms of the ORDER BY clause must be either ASC or DESC.  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 Index *findSortingIndex(  Table *pTab,            /* The table to be sorted */  int base,               /* Cursor number for pTab */  ExprList *pOrderBy,     /* The ORDER BY clause */  Index *pPreferredIdx,   /* Use this index, if possible and not NULL */  int nEqCol,             /* Number of index columns used with == constraints */  int *pbRev              /* Set to 1 if ORDER BY is DESC */){  int i, j;  Index *pMatch;  Index *pIdx;  int sortOrder;  assert( pOrderBy!=0 );  assert( pOrderBy->nExpr>0 );  sortOrder = pOrderBy->a[0].sortOrder & SQLITE_SO_DIRMASK;  for(i=0; i<pOrderBy->nExpr; i++){    Expr *p;    if( (pOrderBy->a[i].sortOrder & SQLITE_SO_DIRMASK)!=sortOrder ){      /* Indices can only be used if all ORDER BY terms are either      ** DESC or ASC.  Indices cannot be used on a mixture. */      return 0;    }    if( (pOrderBy->a[i].sortOrder & SQLITE_SO_TYPEMASK)!=SQLITE_SO_UNK ){      /* Do not sort by index if there is a COLLATE clause */      return 0;    }    p = pOrderBy->a[i].pExpr;    if( p->op!=TK_COLUMN || p->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;    }  }    /* If we get this far, it means the ORDER BY clause consists only of  ** ascending columns in the left-most table of the FROM clause.  Now  ** check for a matching index.  */  pMatch = 0;  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){    int nExpr = pOrderBy->nExpr;    if( pIdx->nColumn < nEqCol || pIdx->nColumn < nExpr ) continue;    for(i=j=0; i<nEqCol; i++){      if( pPreferredIdx->aiColumn[i]!=pIdx->aiColumn[i] ) break;      if( j<nExpr && pOrderBy->a[j].pExpr->iColumn==pIdx->aiColumn[i] ){ j++; }    }    if( i<nEqCol ) continue;    for(i=0; i+j<nExpr; i++){      if( pOrderBy->a[i+j].pExpr->iColumn!=pIdx->aiColumn[i+nEqCol] ) break;    }    if( i+j>=nExpr ){      pMatch = pIdx;      if( pIdx==pPreferredIdx ) break;    }  }  if( pMatch && pbRev ){    *pbRev = sortOrder==SQLITE_SO_DESC;  }  return pMatch;}/*** 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 sqliteWhereEnd() 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 sqliteWhereBegin()**          foreach row3 in t3 do   /**            ...**          end                     \    Code generated**        end                        |-- by sqliteWhereEnd()**      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 sqliteWhereEnd() generates the code to close them.**** 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 *sqliteWhereBegin(  Parse *pParse,       /* The parser context */  SrcList *pTabList,   /* A list of all tables to be scanned */  Expr *pWhere,        /* The WHERE clause */  int pushKey,         /* If TRUE, leave the table key on the stack */  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 */  int loopMask;        /* One bit set for each outer loop */  int haveKey;         /* True if KEY is on the stack */  ExprMaskSet maskSet; /* The expression mask set */  int iDirectEq[32];   /* Term of the form ROWID==X for the N-th table */  int iDirectLt[32];   /* Term of the form ROWID<X or ROWID<=X */  int iDirectGt[32];   /* Term of the form ROWID>X or ROWID>=X */  ExprInfo aExpr[101]; /* The WHERE clause is divided into these expressions */  /* pushKey is only allowed if there is a single table (as in an INSERT or  ** UPDATE statement)  */  assert( pushKey==0 || pTabList->nSrc==1 );  /* 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) ){    sqliteErrorMsg(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( sqlite_malloc_failed ){    sqliteFree(pWInfo);    return 0;  }  pWInfo->pParse = pParse;  pWInfo->pTabList = pTabList;  pWInfo->peakNTab = pWInfo->savedNTab = pParse->nTab;  pWInfo->iBreak = sqliteVdbeMakeLabel(v);  /* Special case: a WHERE clause that is constant.  Evaluate the  ** expression and either jump over all of the code or fall thru.

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美日韩在线亚洲一区蜜芽| 91视视频在线直接观看在线看网页在线看| 日本不卡在线视频| 成人免费电影视频| 911精品产国品一二三产区| 国产欧美日韩在线观看| 亚洲丶国产丶欧美一区二区三区| 国产成人精品免费网站| 日韩欧美三级在线| 午夜久久久久久久久久一区二区| 成人免费视频网站在线观看| 日韩欧美中文一区| 午夜亚洲国产au精品一区二区| 国产福利不卡视频| 精品理论电影在线| 日韩av电影天堂| 欧美三电影在线| 中文字幕一区二区三区精华液| 精品亚洲国内自在自线福利| 欧美男女性生活在线直播观看| 亚洲欧洲av色图| 成人免费观看视频| 中文字幕av在线一区二区三区| 久久国产精品99精品国产 | 国产精品一区在线| 日韩欧美国产一二三区| 日本三级韩国三级欧美三级| 91福利在线导航| 一区二区三区 在线观看视频| 成人动漫一区二区| 国产精品麻豆一区二区| av电影天堂一区二区在线| 亚洲国产高清在线| 懂色中文一区二区在线播放| 国产欧美视频在线观看| 高清国产一区二区| 国产精品久久久久永久免费观看| 国产精品99久久久久久有的能看| 精品人在线二区三区| 国产最新精品精品你懂的| 欧美精品一区二区三区久久久| 蜜桃视频第一区免费观看| 日韩一区二区不卡| 国产资源在线一区| 国产精品欧美一区喷水| 成人av第一页| 亚洲精品五月天| 欧美探花视频资源| 偷拍一区二区三区四区| 91精品国产色综合久久不卡蜜臀 | 国产一区二区毛片| 久久久久久久久岛国免费| 国产成人啪免费观看软件 | 日韩精品国产欧美| 亚洲精品在线电影| 9i在线看片成人免费| 亚洲国产你懂的| 欧美v亚洲v综合ⅴ国产v| 国产主播一区二区| 亚洲精品中文字幕乱码三区| 欧美日韩国产片| 国产一区二区在线观看视频| 最新日韩av在线| 在线播放一区二区三区| 国产麻豆一精品一av一免费 | 国产片一区二区| 色播五月激情综合网| 日韩电影在线观看一区| 久久精品视频在线看| 在线观看区一区二| 久久国产精品99久久久久久老狼 | 亚洲成人综合视频| 精品欧美久久久| 在线欧美一区二区| 国产精品一区二区在线播放| 一区二区三区中文字幕电影 | 成人午夜精品在线| 婷婷成人综合网| 中文字幕在线视频一区| 日韩欧美在线一区二区三区| 成人av在线观| 久久99这里只有精品| 亚洲福中文字幕伊人影院| 国产视频一区二区在线观看| 91精品国产综合久久精品麻豆| 成a人片亚洲日本久久| 美国一区二区三区在线播放| 一区二区免费看| 国产精品久久久久久久第一福利| 欧美一区二区三区四区久久| 色婷婷综合激情| 粉嫩蜜臀av国产精品网站| 免费在线观看一区二区三区| 亚洲天堂成人网| 国产日韩高清在线| 欧美大白屁股肥臀xxxxxx| 欧美色爱综合网| 日本道在线观看一区二区| 成人sese在线| 粉嫩欧美一区二区三区高清影视| 久久99精品国产麻豆不卡| 亚洲成国产人片在线观看| 亚洲欧美另类小说视频| 国产精品的网站| 国产精品五月天| 国产欧美一区二区三区网站| 久久蜜臀中文字幕| 欧美精品一区二区三区在线播放| 欧美区视频在线观看| 欧美精品在欧美一区二区少妇| 91电影在线观看| 欧美网站一区二区| 欧美综合亚洲图片综合区| 91电影在线观看| 在线看不卡av| 欧美日韩免费一区二区三区 | 色综合久久久久综合| 色域天天综合网| 日本精品一区二区三区高清| 色婷婷亚洲综合| 在线观看日韩精品| 欧美日韩午夜影院| 制服丝袜中文字幕亚洲| 欧美一区二区三区系列电影| 日韩一区二区三区免费观看| 日韩精品资源二区在线| 亚洲精品一线二线三线无人区| 久久精品视频一区二区三区| 中文在线一区二区| 亚洲黄色av一区| 日本亚洲欧美天堂免费| 精品一区在线看| 岛国精品在线播放| 91国产免费观看| 欧美亚洲综合色| 亚洲一级片在线观看| 国产精品国产馆在线真实露脸 | 蜜乳av一区二区| 青青草精品视频| 六月丁香综合在线视频| 国产精品996| 91麻豆国产精品久久| 欧美三级电影网| 久久婷婷色综合| 亚洲日本一区二区| 亚洲一区中文日韩| 激情五月婷婷综合| 91在线观看污| 欧美精品三级在线观看| 久久亚洲二区三区| 一区二区三区蜜桃| 精品影院一区二区久久久| 91免费看视频| 精品理论电影在线| 亚洲精品免费在线播放| 日本美女一区二区三区| 丰满白嫩尤物一区二区| 欧美福利视频一区| 国产精品传媒入口麻豆| 午夜精品福利视频网站| 国产一区二区美女诱惑| 欧美日韩一二区| 国产精品久久二区二区| 日本一区中文字幕| 99精品久久免费看蜜臀剧情介绍| 91精品国产麻豆| 1区2区3区精品视频| 韩国一区二区三区| 欧美日韩国产综合一区二区| 国产欧美精品一区二区色综合| 午夜国产精品一区| 成人爱爱电影网址| 久久亚洲一级片| 日韩在线观看一区二区| 99久久国产综合精品色伊| 2014亚洲片线观看视频免费| 偷拍一区二区三区四区| 色婷婷av一区二区三区软件| 国产女人18水真多18精品一级做| 免费在线看一区| 欧美卡1卡2卡| 一区二区三区四区视频精品免费| 国产一区二区三区综合| 欧美一级片在线看| 亚洲国产一区二区三区青草影视| a级精品国产片在线观看| 亚洲精品一区在线观看| 蜜桃av噜噜一区| 日韩一级欧美一级| 日本亚洲免费观看| 91麻豆精品国产91久久久使用方法| 亚洲精品视频在线| 99视频精品全部免费在线| 国产精品久久毛片av大全日韩| 国产精品自在欧美一区| 久久人人爽爽爽人久久久| 久久国产精品区| 亚洲精品一区二区三区影院| 国产剧情一区在线| 国产人成亚洲第一网站在线播放|