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

📄 where.c

📁 一个小型嵌入式数据库SQLite的源码,C语言
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION  /* Add constraints to reduce the search space on a LIKE or GLOB  ** operator.  */  if( isLikeOrGlob(pWC->pParse->db, pExpr, &nPattern, &isComplete) ){    Expr *pLeft, *pRight;    Expr *pStr1, *pStr2;    Expr *pNewExpr1, *pNewExpr2;    int idxNew1, idxNew2;    pLeft = pExpr->pList->a[1].pExpr;    pRight = pExpr->pList->a[0].pExpr;    pStr1 = sqlite3Expr(TK_STRING, 0, 0, 0);    if( pStr1 ){      sqlite3TokenCopy(&pStr1->token, &pRight->token);      pStr1->token.n = nPattern;    }    pStr2 = sqlite3ExprDup(pStr1);    if( pStr2 ){      assert( pStr2->token.dyn );      ++*(u8*)&pStr2->token.z[nPattern-1];    }    pNewExpr1 = sqlite3Expr(TK_GE, sqlite3ExprDup(pLeft), pStr1, 0);    idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);    exprAnalyze(pSrc, pMaskSet, pWC, idxNew1);    pNewExpr2 = sqlite3Expr(TK_LT, sqlite3ExprDup(pLeft), pStr2, 0);    idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);    exprAnalyze(pSrc, pMaskSet, pWC, idxNew2);    pTerm = &pWC->a[idxTerm];    if( isComplete ){      pWC->a[idxNew1].iParent = idxTerm;      pWC->a[idxNew2].iParent = idxTerm;      pTerm->nChild = 2;    }  }#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */#ifndef SQLITE_OMIT_VIRTUALTABLE  /* Add a WO_MATCH auxiliary term to the constraint set if the  ** current expression is of the form:  column MATCH expr.  ** This information is used by the xBestIndex methods of  ** virtual tables.  The native query optimizer does not attempt  ** to do anything with MATCH functions.  */  if( isMatchOfColumn(pExpr) ){    int idxNew;    Expr *pRight, *pLeft;    WhereTerm *pNewTerm;    Bitmask prereqColumn, prereqExpr;    pRight = pExpr->pList->a[0].pExpr;    pLeft = pExpr->pList->a[1].pExpr;    prereqExpr = exprTableUsage(pMaskSet, pRight);    prereqColumn = exprTableUsage(pMaskSet, pLeft);    if( (prereqExpr & prereqColumn)==0 ){      Expr *pNewExpr;      pNewExpr = sqlite3Expr(TK_MATCH, 0, sqlite3ExprDup(pRight), 0);      idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);      pNewTerm = &pWC->a[idxNew];      pNewTerm->prereqRight = prereqExpr;      pNewTerm->leftCursor = pLeft->iTable;      pNewTerm->leftColumn = pLeft->iColumn;      pNewTerm->eOperator = WO_MATCH;      pNewTerm->iParent = idxTerm;      pTerm = &pWC->a[idxTerm];      pTerm->nChild = 1;      pTerm->flags |= TERM_COPIED;      pNewTerm->prereqAll = pTerm->prereqAll;    }  }#endif /* SQLITE_OMIT_VIRTUALTABLE */}/*** 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.**** 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 */  int base,               /* Cursor number for the table to be sorted */  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 = 0;              /* XOR of index and ORDER BY sort direction */  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 */    int termSortOrder; /* Sort order for this term */    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] ||         sqlite3StrICmp(pColl->zName, pIdx->azColl[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;      }    }    assert( pIdx->aSortOrder!=0 );    assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 );    assert( pIdx->aSortOrder[i]==0 || pIdx->aSortOrder[i]==1 );    termSortOrder = pIdx->aSortOrder[i] ^ pTerm->sortOrder;    if( i>nEqCol ){      if( termSortOrder!=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 = termSortOrder;    }    j++;    pTerm++;  }  /* The index can be used for sorting if all terms of the ORDER BY clause  ** are covered.  */  if( j>=nTerm ){    *pbRev = sortOrder!=0;    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( pOrderBy->nExpr==1 && p->op==TK_COLUMN && p->iTable==base          && p->iColumn==-1 ){    *pbRev = pOrderBy->a[0].sortOrder;    return 1;  }  return 0;}/*** Prepare a crude estimate of the logarithm of the input value.** The results need not be exact.  This is only used for estimating** the total cost of performing operatings with O(logN) or O(NlogN)** complexity.  Because N is just a guess, it is no great tragedy if** logN is a little off.*/static double estLog(double N){  double logN = 1;  double x = 10;  while( N>x ){    logN += 1;    x *= 10;  }  return logN;}/*** Two routines for printing the content of an sqlite3_index_info** structure.  Used for testing and debugging only.  If neither** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines** are no-ops.*/#if !defined(SQLITE_OMIT_VIRTUALTABLE) && \        (defined(SQLITE_TEST) || defined(SQLITE_DEBUG))static void TRACE_IDX_INPUTS(sqlite3_index_info *p){  int i;  if( !sqlite3_where_trace ) return;  for(i=0; i<p->nConstraint; i++){    sqlite3DebugPrintf("  constraint[%d]: col=%d termid=%d op=%d usabled=%d\n",       i,       p->aConstraint[i].iColumn,       p->aConstraint[i].iTermOffset,       p->aConstraint[i].op,       p->aConstraint[i].usable);  }  for(i=0; i<p->nOrderBy; i++){    sqlite3DebugPrintf("  orderby[%d]: col=%d desc=%d\n",       i,       p->aOrderBy[i].iColumn,       p->aOrderBy[i].desc);  }}static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){  int i;  if( !sqlite3_where_trace ) return;  for(i=0; i<p->nConstraint; i++){    sqlite3DebugPrintf("  usage[%d]: argvIdx=%d omit=%d\n",       i,       p->aConstraintUsage[i].argvIndex,       p->aConstraintUsage[i].omit);  }  sqlite3DebugPrintf("  idxNum=%d\n", p->idxNum);  sqlite3DebugPrintf("  idxStr=%s\n", p->idxStr);  sqlite3DebugPrintf("  orderByConsumed=%d\n", p->orderByConsumed);  sqlite3DebugPrintf("  estimatedCost=%g\n", p->estimatedCost);}#else#define TRACE_IDX_INPUTS(A)#define TRACE_IDX_OUTPUTS(A)#endif#ifndef SQLITE_OMIT_VIRTUALTABLE/*** Compute the best index for a virtual table.**** The best index is computed by the xBestIndex method of the virtual** table module.  This routine is really just a wrapper that sets up** the sqlite3_index_info structure that is used to communicate with** xBestIndex.**** In a join, this routine might be called multiple times for the** same virtual table.  The sqlite3_index_info structure is created** and initialized on the first invocation and reused on all subsequent** invocations.  The sqlite3_index_info structure is also used when** code is generated to access the virtual table.  The whereInfoDelete() ** routine takes care of freeing the sqlite3_index_info structure after** everybody has finished with it.*/static double bestVirtualIndex(  Parse *pParse,                 /* The parsing context */  WhereClause *pWC,              /* The WHERE clause */  struct SrcList_item *pSrc,     /* The FROM clause term to search */  Bitmask notReady,              /* Mask of cursors that are not available */  ExprList *pOrderBy,            /* The order by clause */  int orderByUsable,             /* True if we can potential sort */  sqlite3_index_info **ppIdxInfo /* Index information passed to xBestIndex */){  Table *pTab = pSrc->pTab;  sqlite3_index_info *pIdxInfo;  struct sqlite3_index_constraint *pIdxCons;  struct sqlite3_index_orderby *pIdxOrderBy;  struct sqlite3_index_constraint_usage *pUsage;  WhereTerm *pTerm;  int i, j;  int nOrderBy;  int rc;  /* If the sqlite3_index_info structure has not been previously  ** allocated and initialized for this virtual table, then allocate  ** and initialize it now  */  pIdxInfo = *ppIdxInfo;  if( pIdxInfo==0 ){    WhereTerm *pTerm;    int nTerm;    TRACE(("Recomputing index info for %s...\n", pTab->zName));    /* Count the number of possible WHERE clause constraints referring    ** to this virtual table */    for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){      if( pTerm->leftCursor != pSrc->iCursor ) continue;      if( pTerm->eOperator==WO_IN ) continue;      nTerm++;    }    /* If the ORDER BY clause contains only columns in the current     ** virtual table then allocate space for the aOrderBy part of    ** the sqlite3_index_info structure.    */    nOrderBy = 0;    if( pOrderBy ){      for(i=0; i<pOrderBy->nExpr; i++){        Expr *pExpr = pOrderBy->a[i].pExpr;        if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break;      }      if( i==pOrderBy->nExpr ){        nOrderBy = pOrderBy->nExpr;      }    }    /* Allocate the sqlite3_index_info structure    */    pIdxInfo = sqliteMalloc( sizeof(*pIdxInfo)                             + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm                             + sizeof(*pIdxOrderBy)*nOrderBy );    if( pIdxInfo==0 ){      sqlite3ErrorMsg(pParse, "out of memory");      return 0.0;    }    *ppIdxInfo = pIdxInfo;    /* Initialize the structure.  The sqlite3_index_info structure contains    ** many fields that are declared "const" to prevent xBestIndex from    ** changing them.  We have to do some funky casting in order to    ** initialize those fields.    */    pIdxCons = (struct sqlite3_index_constraint*)&pIdxInfo[1];    pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm];    pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy];    *(int*)&pIdxInfo->nConstraint = nTerm;    *(int*)&pIdxInfo->nOrderBy = nOrderBy;    *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint = pIdxCons;    *(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy;    *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage =                                                                     pUsage;    for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){      if( pTerm->leftCursor != pSrc->iCursor ) continue;      if( pTerm->eOperator==WO_IN ) continue;      pIdxCons[j].iColumn = pTerm->leftColumn;      pIdxCons[j].iTermOffset = i;      pIdxCons[j].op = pTerm->eOperator;      /* The direct assignment in the previous line is possible only because      ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical.  The      ** following asserts verify this fact. */      assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );      assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );      assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );      assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );      assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );      assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH );      assert( pTerm->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );      j++;    }    for(i=0; i<nOrderBy; i++){      Expr *pExpr = pOrderBy->a[i].pExpr;      pIdxOrderBy[i].iColumn = pExpr->iColumn;

⌨️ 快捷键说明

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