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

📄 resolve.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
  Select *pSelect,      /* The SELECT statement containing the clause */  ExprList *pOrderBy,   /* The ORDER BY or GROUP BY clause to be processed */  const char *zType     /* "ORDER" or "GROUP" */){  int i;  sqlite3 *db = pParse->db;  ExprList *pEList;  struct ExprList_item *pItem;  if( pOrderBy==0 || pParse->db->mallocFailed ) return 0;#if SQLITE_MAX_COLUMN  if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){    sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType);    return 1;  }#endif  pEList = pSelect->pEList;  assert( pEList!=0 );  /* sqlite3SelectNew() guarantees this */  for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){    if( pItem->iCol ){      if( pItem->iCol>pEList->nExpr ){        resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);        return 1;      }      resolveAlias(pParse, pEList, pItem->iCol-1, pItem->pExpr, zType);    }  }  return 0;}/*** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect.** The Name context of the SELECT statement is pNC.  zType is either** "ORDER" or "GROUP" depending on which type of clause pOrderBy is.**** This routine resolves each term of the clause into an expression.** If the order-by term is an integer I between 1 and N (where N is the** number of columns in the result set of the SELECT) then the expression** in the resolution is a copy of the I-th result-set expression.  If** the order-by term is an identify that corresponds to the AS-name of** a result-set expression, then the term resolves to a copy of the** result-set expression.  Otherwise, the expression is resolved in** the usual way - using sqlite3ResolveExprNames().**** This routine returns the number of errors.  If errors occur, then** an appropriate error message might be left in pParse.  (OOM errors** excepted.)*/static int resolveOrderGroupBy(  NameContext *pNC,     /* The name context of the SELECT statement */  Select *pSelect,      /* The SELECT statement holding pOrderBy */  ExprList *pOrderBy,   /* An ORDER BY or GROUP BY clause to resolve */  const char *zType     /* Either "ORDER" or "GROUP", as appropriate */){  int i;                         /* Loop counter */  int iCol;                      /* Column number */  struct ExprList_item *pItem;   /* A term of the ORDER BY clause */  Parse *pParse;                 /* Parsing context */  int nResult;                   /* Number of terms in the result set */  if( pOrderBy==0 ) return 0;  nResult = pSelect->pEList->nExpr;  pParse = pNC->pParse;  for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){    Expr *pE = pItem->pExpr;    iCol = resolveAsName(pParse, pSelect->pEList, pE);    if( iCol<0 ){      return 1;  /* OOM error */    }    if( iCol>0 ){      /* If an AS-name match is found, mark this ORDER BY column as being      ** a copy of the iCol-th result-set column.  The subsequent call to      ** sqlite3ResolveOrderGroupBy() will convert the expression to a      ** copy of the iCol-th result-set expression. */      pItem->iCol = iCol;      continue;    }    if( sqlite3ExprIsInteger(pE, &iCol) ){      /* The ORDER BY term is an integer constant.  Again, set the column      ** number so that sqlite3ResolveOrderGroupBy() will convert the      ** order-by term to a copy of the result-set expression */      if( iCol<1 ){        resolveOutOfRangeError(pParse, zType, i+1, nResult);        return 1;      }      pItem->iCol = iCol;      continue;    }    /* Otherwise, treat the ORDER BY term as an ordinary expression */    pItem->iCol = 0;    if( sqlite3ResolveExprNames(pNC, pE) ){      return 1;    }  }  return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType);}/*** Resolve names in the SELECT statement p and all of its descendents.*/static int resolveSelectStep(Walker *pWalker, Select *p){  NameContext *pOuterNC;  /* Context that contains this SELECT */  NameContext sNC;        /* Name context of this SELECT */  int isCompound;         /* True if p is a compound select */  int nCompound;          /* Number of compound terms processed so far */  Parse *pParse;          /* Parsing context */  ExprList *pEList;       /* Result set expression list */  int i;                  /* Loop counter */  ExprList *pGroupBy;     /* The GROUP BY clause */  Select *pLeftmost;      /* Left-most of SELECT of a compound */  sqlite3 *db;            /* Database connection */    assert( p!=0 );  if( p->selFlags & SF_Resolved ){    return WRC_Prune;  }  pOuterNC = pWalker->u.pNC;  pParse = pWalker->pParse;  db = pParse->db;  /* Normally sqlite3SelectExpand() will be called first and will have  ** already expanded this SELECT.  However, if this is a subquery within  ** an expression, sqlite3ResolveExprNames() will be called without a  ** prior call to sqlite3SelectExpand().  When that happens, let  ** sqlite3SelectPrep() do all of the processing for this SELECT.  ** sqlite3SelectPrep() will invoke both sqlite3SelectExpand() and  ** this routine in the correct order.  */  if( (p->selFlags & SF_Expanded)==0 ){    sqlite3SelectPrep(pParse, p, pOuterNC);    return (pParse->nErr || db->mallocFailed) ? WRC_Abort : WRC_Prune;  }  isCompound = p->pPrior!=0;  nCompound = 0;  pLeftmost = p;  while( p ){    assert( (p->selFlags & SF_Expanded)!=0 );    assert( (p->selFlags & SF_Resolved)==0 );    p->selFlags |= SF_Resolved;    /* Resolve the expressions in the LIMIT and OFFSET clauses. These    ** are not allowed to refer to any names, so pass an empty NameContext.    */    memset(&sNC, 0, sizeof(sNC));    sNC.pParse = pParse;    if( sqlite3ResolveExprNames(&sNC, p->pLimit) ||        sqlite3ResolveExprNames(&sNC, p->pOffset) ){      return WRC_Abort;    }      /* Set up the local name-context to pass to sqlite3ResolveExprNames() to    ** resolve the result-set expression list.    */    sNC.allowAgg = 1;    sNC.pSrcList = p->pSrc;    sNC.pNext = pOuterNC;      /* Resolve names in the result set. */    pEList = p->pEList;    assert( pEList!=0 );    for(i=0; i<pEList->nExpr; i++){      Expr *pX = pEList->a[i].pExpr;      if( sqlite3ResolveExprNames(&sNC, pX) ){        return WRC_Abort;      }    }      /* Recursively resolve names in all subqueries    */    for(i=0; i<p->pSrc->nSrc; i++){      struct SrcList_item *pItem = &p->pSrc->a[i];      if( pItem->pSelect ){        const char *zSavedContext = pParse->zAuthContext;        if( pItem->zName ) pParse->zAuthContext = pItem->zName;        sqlite3ResolveSelectNames(pParse, pItem->pSelect, &sNC);        pParse->zAuthContext = zSavedContext;        if( pParse->nErr || db->mallocFailed ) return WRC_Abort;      }    }      /* If there are no aggregate functions in the result-set, and no GROUP BY     ** expression, do not allow aggregates in any of the other expressions.    */    assert( (p->selFlags & SF_Aggregate)==0 );    pGroupBy = p->pGroupBy;    if( pGroupBy || sNC.hasAgg ){      p->selFlags |= SF_Aggregate;    }else{      sNC.allowAgg = 0;    }      /* If a HAVING clause is present, then there must be a GROUP BY clause.    */    if( p->pHaving && !pGroupBy ){      sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING");      return WRC_Abort;    }      /* Add the expression list to the name-context before parsing the    ** other expressions in the SELECT statement. This is so that    ** expressions in the WHERE clause (etc.) can refer to expressions by    ** aliases in the result set.    **    ** Minor point: If this is the case, then the expression will be    ** re-evaluated for each reference to it.    */    sNC.pEList = p->pEList;    if( sqlite3ResolveExprNames(&sNC, p->pWhere) ||       sqlite3ResolveExprNames(&sNC, p->pHaving)    ){      return WRC_Abort;    }    /* The ORDER BY and GROUP BY clauses may not refer to terms in    ** outer queries     */    sNC.pNext = 0;    sNC.allowAgg = 1;    /* Process the ORDER BY clause for singleton SELECT statements.    ** The ORDER BY clause for compounds SELECT statements is handled    ** below, after all of the result-sets for all of the elements of    ** the compound have been resolved.    */    if( !isCompound && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){      return WRC_Abort;    }    if( db->mallocFailed ){      return WRC_Abort;    }      /* Resolve the GROUP BY clause.  At the same time, make sure     ** the GROUP BY clause does not contain aggregate functions.    */    if( pGroupBy ){      struct ExprList_item *pItem;          if( resolveOrderGroupBy(&sNC, p, pGroupBy, "GROUP") || db->mallocFailed ){        return WRC_Abort;      }      for(i=0, pItem=pGroupBy->a; i<pGroupBy->nExpr; i++, pItem++){        if( ExprHasProperty(pItem->pExpr, EP_Agg) ){          sqlite3ErrorMsg(pParse, "aggregate functions are not allowed in "              "the GROUP BY clause");          return WRC_Abort;        }      }    }    /* Advance to the next term of the compound    */    p = p->pPrior;    nCompound++;  }  /* Resolve the ORDER BY on a compound SELECT after all terms of  ** the compound have been resolved.  */  if( isCompound && resolveCompoundOrderBy(pParse, pLeftmost) ){    return WRC_Abort;  }  return WRC_Prune;}/*** This routine walks an expression tree and resolves references to** table columns and result-set columns.  At the same time, do error** checking on function usage and set a flag if any aggregate functions** are seen.**** To resolve table columns references we look for nodes (or subtrees) of the ** form X.Y.Z or Y.Z or just Z where****      X:   The name of a database.  Ex:  "main" or "temp" or**           the symbolic name assigned to an ATTACH-ed database.****      Y:   The name of a table in a FROM clause.  Or in a trigger**           one of the special names "old" or "new".****      Z:   The name of a column in table Y.**** The node at the root of the subtree is modified as follows:****    Expr.op        Changed to TK_COLUMN**    Expr.pTab      Points to the Table object for X.Y**    Expr.iColumn   The column index in X.Y.  -1 for the rowid.**    Expr.iTable    The VDBE cursor number for X.Y****** To resolve result-set references, look for expression nodes of the** form Z (with no X and Y prefix) where the Z matches the right-hand** size of an AS clause in the result-set of a SELECT.  The Z expression** is replaced by a copy of the left-hand side of the result-set expression.** Table-name and function resolution occurs on the substituted expression** tree.  For example, in:****      SELECT a+b AS x, c+d AS y FROM t1 ORDER BY x;**** The "x" term of the order by is replaced by "a+b" to render:****      SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b;**** Function calls are checked to make sure that the function is ** defined and that the correct number of arguments are specified.** If the function is an aggregate function, then the pNC->hasAgg is** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION.** If an expression contains aggregate functions then the EP_Agg** property on the expression is set.**** An error message is left in pParse if anything is amiss.  The number** if errors is returned.*/int sqlite3ResolveExprNames(   NameContext *pNC,       /* Namespace to resolve expressions in. */  Expr *pExpr             /* The expression to be analyzed. */){  int savedHasAgg;  Walker w;  if( pExpr==0 ) return 0;#if SQLITE_MAX_EXPR_DEPTH>0  {    Parse *pParse = pNC->pParse;    if( sqlite3ExprCheckHeight(pParse, pExpr->nHeight+pNC->pParse->nHeight) ){      return 1;    }    pParse->nHeight += pExpr->nHeight;  }#endif  savedHasAgg = pNC->hasAgg;  pNC->hasAgg = 0;  w.xExprCallback = resolveExprStep;  w.xSelectCallback = resolveSelectStep;  w.pParse = pNC->pParse;  w.u.pNC = pNC;  sqlite3WalkExpr(&w, pExpr);#if SQLITE_MAX_EXPR_DEPTH>0  pNC->pParse->nHeight -= pExpr->nHeight;#endif  if( pNC->nErr>0 ){    ExprSetProperty(pExpr, EP_Error);  }  if( pNC->hasAgg ){    ExprSetProperty(pExpr, EP_Agg);  }else if( savedHasAgg ){    pNC->hasAgg = 1;  }  return ExprHasProperty(pExpr, EP_Error);}/*** Resolve all names in all expressions of a SELECT and in all** decendents of the SELECT, including compounds off of p->pPrior,** subqueries in expressions, and subqueries used as FROM clause** terms.**** See sqlite3ResolveExprNames() for a description of the kinds of** transformations that occur.**** All SELECT statements should have been expanded using** sqlite3SelectExpand() prior to invoking this routine.*/void sqlite3ResolveSelectNames(  Parse *pParse,         /* The parser context */  Select *p,             /* The SELECT statement being coded. */  NameContext *pOuterNC  /* Name context for parent SELECT statement */){  Walker w;  assert( p!=0 );  w.xExprCallback = resolveExprStep;  w.xSelectCallback = resolveSelectStep;  w.pParse = pParse;  w.u.pNC = pOuterNC;  sqlite3WalkSelect(&w, p);}

⌨️ 快捷键说明

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