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

📄 resolve.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    return 1;  }}/*** This routine is callback for sqlite3WalkExpr().**** Resolve symbolic names into TK_COLUMN operators for the current** node in the expression tree.  Return 0 to continue the search down** the tree or 2 to abort the tree walk.**** This routine also does error checking and name resolution for** function names.  The operator for aggregate functions is changed** to TK_AGG_FUNCTION.*/static int resolveExprStep(Walker *pWalker, Expr *pExpr){  NameContext *pNC;  Parse *pParse;  pNC = pWalker->u.pNC;  assert( pNC!=0 );  pParse = pNC->pParse;  assert( pParse==pWalker->pParse );  if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return WRC_Prune;  ExprSetProperty(pExpr, EP_Resolved);#ifndef NDEBUG  if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){    SrcList *pSrcList = pNC->pSrcList;    int i;    for(i=0; i<pNC->pSrcList->nSrc; i++){      assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab);    }  }#endif  switch( pExpr->op ){    /* A lone identifier is the name of a column.    */    case TK_ID: {      lookupName(pParse, 0, 0, &pExpr->token, pNC, pExpr);      return WRC_Prune;    }      /* A table name and column name:     ID.ID    ** Or a database, table and column:  ID.ID.ID    */    case TK_DOT: {      Token *pColumn;      Token *pTable;      Token *pDb;      Expr *pRight;      /* if( pSrcList==0 ) break; */      pRight = pExpr->pRight;      if( pRight->op==TK_ID ){        pDb = 0;        pTable = &pExpr->pLeft->token;        pColumn = &pRight->token;      }else{        assert( pRight->op==TK_DOT );        pDb = &pExpr->pLeft->token;        pTable = &pRight->pLeft->token;        pColumn = &pRight->pRight->token;      }      lookupName(pParse, pDb, pTable, pColumn, pNC, pExpr);      return WRC_Prune;    }    /* Resolve function names    */    case TK_CONST_FUNC:    case TK_FUNCTION: {      ExprList *pList = pExpr->pList;    /* The argument list */      int n = pList ? pList->nExpr : 0;  /* Number of arguments */      int no_such_func = 0;       /* True if no such function exists */      int wrong_num_args = 0;     /* True if wrong number of arguments */      int is_agg = 0;             /* True if is an aggregate function */      int auth;                   /* Authorization to use the function */      int nId;                    /* Number of characters in function name */      const char *zId;            /* The function name. */      FuncDef *pDef;              /* Information about the function */      int enc = ENC(pParse->db);  /* The database encoding */      zId = (char*)pExpr->token.z;      nId = pExpr->token.n;      pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);      if( pDef==0 ){        pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0);        if( pDef==0 ){          no_such_func = 1;        }else{          wrong_num_args = 1;        }      }else{        is_agg = pDef->xFunc==0;      }#ifndef SQLITE_OMIT_AUTHORIZATION      if( pDef ){        auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);        if( auth!=SQLITE_OK ){          if( auth==SQLITE_DENY ){            sqlite3ErrorMsg(pParse, "not authorized to use function: %s",                                    pDef->zName);            pNC->nErr++;          }          pExpr->op = TK_NULL;          return WRC_Prune;        }      }#endif      if( is_agg && !pNC->allowAgg ){        sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);        pNC->nErr++;        is_agg = 0;      }else if( no_such_func ){        sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);        pNC->nErr++;      }else if( wrong_num_args ){        sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",             nId, zId);        pNC->nErr++;      }      if( is_agg ){        pExpr->op = TK_AGG_FUNCTION;        pNC->hasAgg = 1;      }      if( is_agg ) pNC->allowAgg = 0;      sqlite3WalkExprList(pWalker, pList);      if( is_agg ) pNC->allowAgg = 1;      /* FIX ME:  Compute pExpr->affinity based on the expected return      ** type of the function       */      return WRC_Prune;    }#ifndef SQLITE_OMIT_SUBQUERY    case TK_SELECT:    case TK_EXISTS:#endif    case TK_IN: {      if( pExpr->pSelect ){        int nRef = pNC->nRef;#ifndef SQLITE_OMIT_CHECK        if( pNC->isCheck ){          sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");        }#endif        sqlite3WalkSelect(pWalker, pExpr->pSelect);        assert( pNC->nRef>=nRef );        if( nRef!=pNC->nRef ){          ExprSetProperty(pExpr, EP_VarSelect);        }      }      break;    }#ifndef SQLITE_OMIT_CHECK    case TK_VARIABLE: {      if( pNC->isCheck ){        sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");      }      break;    }#endif  }  return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;}/*** pEList is a list of expressions which are really the result set of the** a SELECT statement.  pE is a term in an ORDER BY or GROUP BY clause.** This routine checks to see if pE is a simple identifier which corresponds** to the AS-name of one of the terms of the expression list.  If it is,** this routine return an integer between 1 and N where N is the number of** elements in pEList, corresponding to the matching entry.  If there is** no match, or if pE is not a simple identifier, then this routine** return 0.**** pEList has been resolved.  pE has not.*/static int resolveAsName(  Parse *pParse,     /* Parsing context for error messages */  ExprList *pEList,  /* List of expressions to scan */  Expr *pE           /* Expression we are trying to match */){  int i;             /* Loop counter */  if( pE->op==TK_ID || (pE->op==TK_STRING && pE->token.z[0]!='\'') ){    sqlite3 *db = pParse->db;    char *zCol = sqlite3NameFromToken(db, &pE->token);    if( zCol==0 ){      return -1;    }    for(i=0; i<pEList->nExpr; i++){      char *zAs = pEList->a[i].zName;      if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){        sqlite3DbFree(db, zCol);        return i+1;      }    }    sqlite3DbFree(db, zCol);  }  return 0;}/*** pE is a pointer to an expression which is a single term in the** ORDER BY of a compound SELECT.  The expression has not been** name resolved.**** At the point this routine is called, we already know that the** ORDER BY term is not an integer index into the result set.  That** case is handled by the calling routine.**** Attempt to match pE against result set columns in the left-most** SELECT statement.  Return the index i of the matching column,** as an indication to the caller that it should sort by the i-th column.** The left-most column is 1.  In other words, the value returned is the** same integer value that would be used in the SQL statement to indicate** the column.**** If there is no match, return 0.  Return -1 if an error occurs.*/static int resolveOrderByTermToExprList(  Parse *pParse,     /* Parsing context for error messages */  Select *pSelect,   /* The SELECT statement with the ORDER BY clause */  Expr *pE           /* The specific ORDER BY term */){  int i;             /* Loop counter */  ExprList *pEList;  /* The columns of the result set */  NameContext nc;    /* Name context for resolving pE */  assert( sqlite3ExprIsInteger(pE, &i)==0 );  pEList = pSelect->pEList;  /* Resolve all names in the ORDER BY term expression  */  memset(&nc, 0, sizeof(nc));  nc.pParse = pParse;  nc.pSrcList = pSelect->pSrc;  nc.pEList = pEList;  nc.allowAgg = 1;  nc.nErr = 0;  if( sqlite3ResolveExprNames(&nc, pE) ){    sqlite3ErrorClear(pParse);    return 0;  }  /* Try to match the ORDER BY expression against an expression  ** in the result set.  Return an 1-based index of the matching  ** result-set entry.  */  for(i=0; i<pEList->nExpr; i++){    if( sqlite3ExprCompare(pEList->a[i].pExpr, pE) ){      return i+1;    }  }  /* If no match, return 0. */  return 0;}/*** Generate an ORDER BY or GROUP BY term out-of-range error.*/static void resolveOutOfRangeError(  Parse *pParse,         /* The error context into which to write the error */  const char *zType,     /* "ORDER" or "GROUP" */  int i,                 /* The index (1-based) of the term out of range */  int mx                 /* Largest permissible value of i */){  sqlite3ErrorMsg(pParse,     "%r %s BY term out of range - should be "    "between 1 and %d", i, zType, mx);}/*** Analyze the ORDER BY clause in a compound SELECT statement.   Modify** each term of the ORDER BY clause is a constant integer between 1** and N where N is the number of columns in the compound SELECT.**** ORDER BY terms that are already an integer between 1 and N are** unmodified.  ORDER BY terms that are integers outside the range of** 1 through N generate an error.  ORDER BY terms that are expressions** are matched against result set expressions of compound SELECT** beginning with the left-most SELECT and working toward the right.** At the first match, the ORDER BY expression is transformed into** the integer column number.**** Return the number of errors seen.*/static int resolveCompoundOrderBy(  Parse *pParse,        /* Parsing context.  Leave error messages here */  Select *pSelect       /* The SELECT statement containing the ORDER BY */){  int i;  ExprList *pOrderBy;  ExprList *pEList;  sqlite3 *db;  int moreToDo = 1;  pOrderBy = pSelect->pOrderBy;  if( pOrderBy==0 ) return 0;  db = pParse->db;#if SQLITE_MAX_COLUMN  if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){    sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause");    return 1;  }#endif  for(i=0; i<pOrderBy->nExpr; i++){    pOrderBy->a[i].done = 0;  }  pSelect->pNext = 0;  while( pSelect->pPrior ){    pSelect->pPrior->pNext = pSelect;    pSelect = pSelect->pPrior;  }  while( pSelect && moreToDo ){    struct ExprList_item *pItem;    moreToDo = 0;    pEList = pSelect->pEList;    assert( pEList!=0 );    for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){      int iCol = -1;      Expr *pE, *pDup;      if( pItem->done ) continue;      pE = pItem->pExpr;      if( sqlite3ExprIsInteger(pE, &iCol) ){        if( iCol<0 || iCol>pEList->nExpr ){          resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);          return 1;        }      }else{        iCol = resolveAsName(pParse, pEList, pE);        if( iCol==0 ){          pDup = sqlite3ExprDup(db, pE);          if( !db->mallocFailed ){            assert(pDup);            iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup);          }          sqlite3ExprDelete(db, pDup);        }        if( iCol<0 ){          return 1;        }      }      if( iCol>0 ){        CollSeq *pColl = pE->pColl;        int flags = pE->flags & EP_ExpCollate;        sqlite3ExprDelete(db, pE);        pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0, 0, 0);        if( pE==0 ) return 1;        pE->pColl = pColl;        pE->flags |= EP_IntValue | flags;        pE->iTable = iCol;        pItem->iCol = iCol;        pItem->done = 1;      }else{        moreToDo = 1;      }    }    pSelect = pSelect->pNext;  }  for(i=0; i<pOrderBy->nExpr; i++){    if( pOrderBy->a[i].done==0 ){      sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any "            "column in the result set", i+1);      return 1;    }  }  return 0;}/*** Check every term in the ORDER BY or GROUP BY clause pOrderBy of** the SELECT statement pSelect.  If any term is reference to a** result set expression (as determined by the ExprList.a.iCol field)** then convert that term into a copy of the corresponding result set** column.**** If any errors are detected, add an error message to pParse and** return non-zero.  Return zero if no errors are seen.*/int sqlite3ResolveOrderGroupBy(  Parse *pParse,        /* Parsing context.  Leave error messages here */

⌨️ 快捷键说明

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