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

📄 expr.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span);      }      if( pRight->flags & EP_ExpCollate ){        pNew->flags |= EP_ExpCollate;        pNew->pColl = pRight->pColl;      }    }    if( pLeft->flags & EP_ExpCollate ){      pNew->flags |= EP_ExpCollate;      pNew->pColl = pLeft->pColl;    }  }  exprSetHeight(pNew);  return pNew;}/*** Works like sqlite3Expr() except that it takes an extra Parse*** argument and notifies the associated connection object if malloc fails.*/Expr *sqlite3PExpr(  Parse *pParse,          /* Parsing context */  int op,                 /* Expression opcode */  Expr *pLeft,            /* Left operand */  Expr *pRight,           /* Right operand */  const Token *pToken     /* Argument token */){  Expr *p = sqlite3Expr(pParse->db, op, pLeft, pRight, pToken);  if( p ){    sqlite3ExprCheckHeight(pParse, p->nHeight);  }  return p;}/*** When doing a nested parse, you can include terms in an expression** that look like this:   #1 #2 ...  These terms refer to registers** in the virtual machine.  #N is the N-th register.**** This routine is called by the parser to deal with on of those terms.** It immediately generates code to store the value in a memory location.** The returns an expression that will code to extract the value from** that memory location as needed.*/Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){  Vdbe *v = pParse->pVdbe;  Expr *p;  if( pParse->nested==0 ){    sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", pToken);    return sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);  }  if( v==0 ) return 0;  p = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, pToken);  if( p==0 ){    return 0;  /* Malloc failed */  }  p->iTable = atoi((char*)&pToken->z[1]);  return p;}/*** Join two expressions using an AND operator.  If either expression is** NULL, then just return the other expression.*/Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){  if( pLeft==0 ){    return pRight;  }else if( pRight==0 ){    return pLeft;  }else{    return sqlite3Expr(db, TK_AND, pLeft, pRight, 0);  }}/*** Set the Expr.span field of the given expression to span all** text between the two given tokens.  Both tokens must be pointing** at the same string.*/void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){  assert( pRight!=0 );  assert( pLeft!=0 );  if( pExpr ){    pExpr->span.z = pLeft->z;    pExpr->span.n = pRight->n + (pRight->z - pLeft->z);  }}/*** Construct a new expression node for a function with multiple** arguments.*/Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){  Expr *pNew;  sqlite3 *db = pParse->db;  assert( pToken );  pNew = sqlite3DbMallocZero(db, sizeof(Expr) );  if( pNew==0 ){    sqlite3ExprListDelete(db, pList); /* Avoid leaking memory when malloc fails */    return 0;  }  pNew->op = TK_FUNCTION;  pNew->pList = pList;  assert( pToken->dyn==0 );  pNew->token = *pToken;  pNew->span = pNew->token;  sqlite3ExprSetHeight(pParse, pNew);  return pNew;}/*** Assign a variable number to an expression that encodes a wildcard** in the original SQL statement.  **** Wildcards consisting of a single "?" are assigned the next sequential** variable number.**** Wildcards of the form "?nnn" are assigned the number "nnn".  We make** sure "nnn" is not too be to avoid a denial of service attack when** the SQL statement comes from an external source.**** Wildcards of the form ":aaa" or "$aaa" are assigned the same number** as the previous instance of the same wildcard.  Or if this is the first** instance of the wildcard, the next sequenial variable number is** assigned.*/void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){  Token *pToken;  sqlite3 *db = pParse->db;  if( pExpr==0 ) return;  pToken = &pExpr->token;  assert( pToken->n>=1 );  assert( pToken->z!=0 );  assert( pToken->z[0]!=0 );  if( pToken->n==1 ){    /* Wildcard of the form "?".  Assign the next variable number */    pExpr->iTable = ++pParse->nVar;  }else if( pToken->z[0]=='?' ){    /* Wildcard of the form "?nnn".  Convert "nnn" to an integer and    ** use it as the variable number */    int i;    pExpr->iTable = i = atoi((char*)&pToken->z[1]);    testcase( i==0 );    testcase( i==1 );    testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );    testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );    if( i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){      sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",          db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);    }    if( i>pParse->nVar ){      pParse->nVar = i;    }  }else{    /* Wildcards of the form ":aaa" or "$aaa".  Reuse the same variable    ** number as the prior appearance of the same name, or if the name    ** has never appeared before, reuse the same variable number    */    int i, n;    n = pToken->n;    for(i=0; i<pParse->nVarExpr; i++){      Expr *pE;      if( (pE = pParse->apVarExpr[i])!=0          && pE->token.n==n          && memcmp(pE->token.z, pToken->z, n)==0 ){        pExpr->iTable = pE->iTable;        break;      }    }    if( i>=pParse->nVarExpr ){      pExpr->iTable = ++pParse->nVar;      if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){        pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10;        pParse->apVarExpr =            sqlite3DbReallocOrFree(              db,              pParse->apVarExpr,              pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0])            );      }      if( !db->mallocFailed ){        assert( pParse->apVarExpr!=0 );        pParse->apVarExpr[pParse->nVarExpr++] = pExpr;      }    }  }   if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){    sqlite3ErrorMsg(pParse, "too many SQL variables");  }}/*** Recursively delete an expression tree.*/void sqlite3ExprDelete(sqlite3 *db, Expr *p){  if( p==0 ) return;  if( p->span.dyn ) sqlite3DbFree(db, (char*)p->span.z);  if( p->token.dyn ) sqlite3DbFree(db, (char*)p->token.z);  sqlite3ExprDelete(db, p->pLeft);  sqlite3ExprDelete(db, p->pRight);  sqlite3ExprListDelete(db, p->pList);  sqlite3SelectDelete(db, p->pSelect);  sqlite3DbFree(db, p);}/*** The Expr.token field might be a string literal that is quoted.** If so, remove the quotation marks.*/void sqlite3DequoteExpr(sqlite3 *db, Expr *p){  if( ExprHasAnyProperty(p, EP_Dequoted) ){    return;  }  ExprSetProperty(p, EP_Dequoted);  if( p->token.dyn==0 ){    sqlite3TokenCopy(db, &p->token, &p->token);  }  sqlite3Dequote((char*)p->token.z);}/*** The following group of routines make deep copies of expressions,** expression lists, ID lists, and select statements.  The copies can** be deleted (by being passed to their respective ...Delete() routines)** without effecting the originals.**** The expression list, ID, and source lists return by sqlite3ExprListDup(),** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded ** by subsequent calls to sqlite*ListAppend() routines.**** Any tables that the SrcList might point to are not duplicated.*/Expr *sqlite3ExprDup(sqlite3 *db, Expr *p){  Expr *pNew;  if( p==0 ) return 0;  pNew = sqlite3DbMallocRaw(db, sizeof(*p) );  if( pNew==0 ) return 0;  memcpy(pNew, p, sizeof(*pNew));  if( p->token.z!=0 ){    pNew->token.z = (u8*)sqlite3DbStrNDup(db, (char*)p->token.z, p->token.n);    pNew->token.dyn = 1;  }else{    assert( pNew->token.z==0 );  }  pNew->span.z = 0;  pNew->pLeft = sqlite3ExprDup(db, p->pLeft);  pNew->pRight = sqlite3ExprDup(db, p->pRight);  pNew->pList = sqlite3ExprListDup(db, p->pList);  pNew->pSelect = sqlite3SelectDup(db, p->pSelect);  return pNew;}void sqlite3TokenCopy(sqlite3 *db, Token *pTo, Token *pFrom){  if( pTo->dyn ) sqlite3DbFree(db, (char*)pTo->z);  if( pFrom->z ){    pTo->n = pFrom->n;    pTo->z = (u8*)sqlite3DbStrNDup(db, (char*)pFrom->z, pFrom->n);    pTo->dyn = 1;  }else{    pTo->z = 0;  }}ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p){  ExprList *pNew;  struct ExprList_item *pItem, *pOldItem;  int i;  if( p==0 ) return 0;  pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) );  if( pNew==0 ) return 0;  pNew->iECursor = 0;  pNew->nExpr = pNew->nAlloc = p->nExpr;  pNew->a = pItem = sqlite3DbMallocRaw(db,  p->nExpr*sizeof(p->a[0]) );  if( pItem==0 ){    sqlite3DbFree(db, pNew);    return 0;  }   pOldItem = p->a;  for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){    Expr *pNewExpr, *pOldExpr;    pItem->pExpr = pNewExpr = sqlite3ExprDup(db, pOldExpr = pOldItem->pExpr);    if( pOldExpr->span.z!=0 && pNewExpr ){      /* Always make a copy of the span for top-level expressions in the      ** expression list.  The logic in SELECT processing that determines      ** the names of columns in the result set needs this information */      sqlite3TokenCopy(db, &pNewExpr->span, &pOldExpr->span);    }    assert( pNewExpr==0 || pNewExpr->span.z!=0             || pOldExpr->span.z==0            || db->mallocFailed );    pItem->zName = sqlite3DbStrDup(db, pOldItem->zName);    pItem->sortOrder = pOldItem->sortOrder;    pItem->done = 0;    pItem->iCol = pOldItem->iCol;    pItem->iAlias = pOldItem->iAlias;  }  return pNew;}/*** If cursors, triggers, views and subqueries are all omitted from** the build, then none of the following routines, except for ** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes** called with a NULL argument.*/#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ || !defined(SQLITE_OMIT_SUBQUERY)SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p){  SrcList *pNew;  int i;  int nByte;  if( p==0 ) return 0;  nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);  pNew = sqlite3DbMallocRaw(db, nByte );  if( pNew==0 ) return 0;  pNew->nSrc = pNew->nAlloc = p->nSrc;  for(i=0; i<p->nSrc; i++){    struct SrcList_item *pNewItem = &pNew->a[i];    struct SrcList_item *pOldItem = &p->a[i];    Table *pTab;    pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);    pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);    pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);    pNewItem->jointype = pOldItem->jointype;    pNewItem->iCursor = pOldItem->iCursor;    pNewItem->isPopulated = pOldItem->isPopulated;    pTab = pNewItem->pTab = pOldItem->pTab;    if( pTab ){      pTab->nRef++;    }    pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect);    pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn);    pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing);    pNewItem->colUsed = pOldItem->colUsed;  }  return pNew;}IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){  IdList *pNew;  int i;  if( p==0 ) return 0;  pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) );  if( pNew==0 ) return 0;  pNew->nId = pNew->nAlloc = p->nId;  pNew->a = sqlite3DbMallocRaw(db, p->nId*sizeof(p->a[0]) );  if( pNew->a==0 ){    sqlite3DbFree(db, pNew);    return 0;  }  for(i=0; i<p->nId; i++){    struct IdList_item *pNewItem = &pNew->a[i];    struct IdList_item *pOldItem = &p->a[i];    pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);    pNewItem->idx = pOldItem->idx;  }  return pNew;}Select *sqlite3SelectDup(sqlite3 *db, Select *p){  Select *pNew;  if( p==0 ) return 0;  pNew = sqlite3DbMallocRaw(db, sizeof(*p) );  if( pNew==0 ) return 0;  pNew->pEList = sqlite3ExprListDup(db, p->pEList);  pNew->pSrc = sqlite3SrcListDup(db, p->pSrc);  pNew->pWhere = sqlite3ExprDup(db, p->pWhere);  pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy);  pNew->pHaving = sqlite3ExprDup(db, p->pHaving);  pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy);  pNew->op = p->op;  pNew->pPrior = sqlite3SelectDup(db, p->pPrior);  pNew->pLimit = sqlite3ExprDup(db, p->pLimit);  pNew->pOffset = sqlite3ExprDup(db, p->pOffset);  pNew->iLimit = 0;  pNew->iOffset = 0;  pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;  pNew->pRightmost = 0;  pNew->addrOpenEphm[0] = -1;  pNew->addrOpenEphm[1] = -1;  pNew->addrOpenEphm[2] = -1;  return pNew;}#elseSelect *sqlite3SelectDup(sqlite3 *db, Select *p){  assert( p==0 );  return 0;}#endif/*** Add a new element to the end of an expression list.  If pList is** initially NULL, then create a new expression list.*/ExprList *sqlite3ExprListAppend(  Parse *pParse,          /* Parsing context */  ExprList *pList,        /* List to which to append. Might be NULL */  Expr *pExpr,            /* Expression to be appended */  Token *pName            /* AS keyword for the expression */){  sqlite3 *db = pParse->db;  if( pList==0 ){    pList = sqlite3DbMallocZero(db, sizeof(ExprList) );    if( pList==0 ){      goto no_mem;    }    assert( pList->nAlloc==0 );  }

⌨️ 快捷键说明

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