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

📄 expr.c

📁 sqlite数据库管理系统开放源码
💻 C
📖 第 1 页 / 共 4 页
字号:
      int is_agg = 0;             /* True if is an aggregate function */      int i;      int nId;                    /* Number of characters in function name */      const char *zId;            /* The function name. */      FuncDef *pDef;      getFunctionName(pExpr, &zId, &nId);      pDef = sqliteFindFunction(pParse->db, zId, nId, n, 0);      if( pDef==0 ){        pDef = sqliteFindFunction(pParse->db, zId, nId, -1, 0);        if( pDef==0 ){          no_such_func = 1;        }else{          wrong_num_args = 1;        }      }else{        is_agg = pDef->xFunc==0;      }      if( is_agg && !allowAgg ){        sqliteErrorMsg(pParse, "misuse of aggregate function %.*s()", nId, zId);        nErr++;        is_agg = 0;      }else if( no_such_func ){        sqliteErrorMsg(pParse, "no such function: %.*s", nId, zId);        nErr++;      }else if( wrong_num_args ){        sqliteErrorMsg(pParse,"wrong number of arguments to function %.*s()",             nId, zId);        nErr++;      }      if( is_agg ){        pExpr->op = TK_AGG_FUNCTION;        if( pIsAgg ) *pIsAgg = 1;      }      for(i=0; nErr==0 && i<n; i++){        nErr = sqliteExprCheck(pParse, pExpr->pList->a[i].pExpr,                               allowAgg && !is_agg, pIsAgg);      }      if( pDef==0 ){        /* Already reported an error */      }else if( pDef->dataType>=0 ){        if( pDef->dataType<n ){          pExpr->dataType =              sqliteExprType(pExpr->pList->a[pDef->dataType].pExpr);        }else{          pExpr->dataType = SQLITE_SO_NUM;        }      }else if( pDef->dataType==SQLITE_ARGS ){        pDef->dataType = SQLITE_SO_TEXT;        for(i=0; i<n; i++){          if( sqliteExprType(pExpr->pList->a[i].pExpr)==SQLITE_SO_NUM ){            pExpr->dataType = SQLITE_SO_NUM;            break;          }        }      }else if( pDef->dataType==SQLITE_NUMERIC ){        pExpr->dataType = SQLITE_SO_NUM;      }else{        pExpr->dataType = SQLITE_SO_TEXT;      }    }    default: {      if( pExpr->pLeft ){        nErr = sqliteExprCheck(pParse, pExpr->pLeft, allowAgg, pIsAgg);      }      if( nErr==0 && pExpr->pRight ){        nErr = sqliteExprCheck(pParse, pExpr->pRight, allowAgg, pIsAgg);      }      if( nErr==0 && pExpr->pList ){        int n = pExpr->pList->nExpr;        int i;        for(i=0; nErr==0 && i<n; i++){          Expr *pE2 = pExpr->pList->a[i].pExpr;          nErr = sqliteExprCheck(pParse, pE2, allowAgg, pIsAgg);        }      }      break;    }  }  return nErr;}/*** Return either SQLITE_SO_NUM or SQLITE_SO_TEXT to indicate whether the** given expression should sort as numeric values or as text.**** The sqliteExprResolveIds() and sqliteExprCheck() routines must have** both been called on the expression before it is passed to this routine.*/int sqliteExprType(Expr *p){  if( p==0 ) return SQLITE_SO_NUM;  while( p ) switch( p->op ){    case TK_PLUS:    case TK_MINUS:    case TK_STAR:    case TK_SLASH:    case TK_AND:    case TK_OR:    case TK_ISNULL:    case TK_NOTNULL:    case TK_NOT:    case TK_UMINUS:    case TK_UPLUS:    case TK_BITAND:    case TK_BITOR:    case TK_BITNOT:    case TK_LSHIFT:    case TK_RSHIFT:    case TK_REM:    case TK_INTEGER:    case TK_FLOAT:    case TK_IN:    case TK_BETWEEN:    case TK_GLOB:    case TK_LIKE:      return SQLITE_SO_NUM;    case TK_STRING:    case TK_NULL:    case TK_CONCAT:    case TK_VARIABLE:      return SQLITE_SO_TEXT;    case TK_LT:    case TK_LE:    case TK_GT:    case TK_GE:    case TK_NE:    case TK_EQ:      if( sqliteExprType(p->pLeft)==SQLITE_SO_NUM ){        return SQLITE_SO_NUM;      }      p = p->pRight;      break;    case TK_AS:      p = p->pLeft;      break;    case TK_COLUMN:    case TK_FUNCTION:    case TK_AGG_FUNCTION:      return p->dataType;    case TK_SELECT:      assert( p->pSelect );      assert( p->pSelect->pEList );      assert( p->pSelect->pEList->nExpr>0 );      p = p->pSelect->pEList->a[0].pExpr;      break;    case TK_CASE: {      if( p->pRight && sqliteExprType(p->pRight)==SQLITE_SO_NUM ){        return SQLITE_SO_NUM;      }      if( p->pList ){        int i;        ExprList *pList = p->pList;        for(i=1; i<pList->nExpr; i+=2){          if( sqliteExprType(pList->a[i].pExpr)==SQLITE_SO_NUM ){            return SQLITE_SO_NUM;          }        }      }      return SQLITE_SO_TEXT;    }    default:      assert( p->op==TK_ABORT );  /* Can't Happen */      break;  }  return SQLITE_SO_NUM;}/*** Generate code into the current Vdbe to evaluate the given** expression and leave the result on the top of stack.*/void sqliteExprCode(Parse *pParse, Expr *pExpr){  Vdbe *v = pParse->pVdbe;  int op;  if( v==0 || pExpr==0 ) return;  switch( pExpr->op ){    case TK_PLUS:     op = OP_Add;      break;    case TK_MINUS:    op = OP_Subtract; break;    case TK_STAR:     op = OP_Multiply; break;    case TK_SLASH:    op = OP_Divide;   break;    case TK_AND:      op = OP_And;      break;    case TK_OR:       op = OP_Or;       break;    case TK_LT:       op = OP_Lt;       break;    case TK_LE:       op = OP_Le;       break;    case TK_GT:       op = OP_Gt;       break;    case TK_GE:       op = OP_Ge;       break;    case TK_NE:       op = OP_Ne;       break;    case TK_EQ:       op = OP_Eq;       break;    case TK_ISNULL:   op = OP_IsNull;   break;    case TK_NOTNULL:  op = OP_NotNull;  break;    case TK_NOT:      op = OP_Not;      break;    case TK_UMINUS:   op = OP_Negative; break;    case TK_BITAND:   op = OP_BitAnd;   break;    case TK_BITOR:    op = OP_BitOr;    break;    case TK_BITNOT:   op = OP_BitNot;   break;    case TK_LSHIFT:   op = OP_ShiftLeft;  break;    case TK_RSHIFT:   op = OP_ShiftRight; break;    case TK_REM:      op = OP_Remainder;  break;    default: break;  }  switch( pExpr->op ){    case TK_COLUMN: {      if( pParse->useAgg ){        sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);      }else if( pExpr->iColumn>=0 ){        sqliteVdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);      }else{        sqliteVdbeAddOp(v, OP_Recno, pExpr->iTable, 0);      }      break;    }    case TK_STRING:    case TK_FLOAT:    case TK_INTEGER: {      if( pExpr->op==TK_INTEGER && sqliteFitsIn32Bits(pExpr->token.z) ){        sqliteVdbeAddOp(v, OP_Integer, atoi(pExpr->token.z), 0);      }else{        sqliteVdbeAddOp(v, OP_String, 0, 0);      }      assert( pExpr->token.z );      sqliteVdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n);      sqliteVdbeDequoteP3(v, -1);      break;    }    case TK_NULL: {      sqliteVdbeAddOp(v, OP_String, 0, 0);      break;    }    case TK_VARIABLE: {      sqliteVdbeAddOp(v, OP_Variable, pExpr->iTable, 0);      break;    }    case TK_LT:    case TK_LE:    case TK_GT:    case TK_GE:    case TK_NE:    case TK_EQ: {      if( pParse->db->file_format>=4 && sqliteExprType(pExpr)==SQLITE_SO_TEXT ){        op += 6;  /* Convert numeric opcodes to text opcodes */      }      /* Fall through into the next case */    }    case TK_AND:    case TK_OR:    case TK_PLUS:    case TK_STAR:    case TK_MINUS:    case TK_REM:    case TK_BITAND:    case TK_BITOR:    case TK_SLASH: {      sqliteExprCode(pParse, pExpr->pLeft);      sqliteExprCode(pParse, pExpr->pRight);      sqliteVdbeAddOp(v, op, 0, 0);      break;    }    case TK_LSHIFT:    case TK_RSHIFT: {      sqliteExprCode(pParse, pExpr->pRight);      sqliteExprCode(pParse, pExpr->pLeft);      sqliteVdbeAddOp(v, op, 0, 0);      break;    }    case TK_CONCAT: {      sqliteExprCode(pParse, pExpr->pLeft);      sqliteExprCode(pParse, pExpr->pRight);      sqliteVdbeAddOp(v, OP_Concat, 2, 0);      break;    }    case TK_UMINUS: {      assert( pExpr->pLeft );      if( pExpr->pLeft->op==TK_FLOAT || pExpr->pLeft->op==TK_INTEGER ){        Token *p = &pExpr->pLeft->token;        char *z = sqliteMalloc( p->n + 2 );        sprintf(z, "-%.*s", p->n, p->z);        if( pExpr->pLeft->op==TK_INTEGER && sqliteFitsIn32Bits(z) ){          sqliteVdbeAddOp(v, OP_Integer, atoi(z), 0);        }else{          sqliteVdbeAddOp(v, OP_String, 0, 0);        }        sqliteVdbeChangeP3(v, -1, z, p->n+1);        sqliteFree(z);        break;      }      /* Fall through into TK_NOT */    }    case TK_BITNOT:    case TK_NOT: {      sqliteExprCode(pParse, pExpr->pLeft);      sqliteVdbeAddOp(v, op, 0, 0);      break;    }    case TK_ISNULL:    case TK_NOTNULL: {      int dest;      sqliteVdbeAddOp(v, OP_Integer, 1, 0);      sqliteExprCode(pParse, pExpr->pLeft);      dest = sqliteVdbeCurrentAddr(v) + 2;      sqliteVdbeAddOp(v, op, 1, dest);      sqliteVdbeAddOp(v, OP_AddImm, -1, 0);      break;    }    case TK_AGG_FUNCTION: {      sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);      break;    }    case TK_GLOB:    case TK_LIKE:    case TK_FUNCTION: {      ExprList *pList = pExpr->pList;      int nExpr = pList ? pList->nExpr : 0;      FuncDef *pDef;      int nId;      const char *zId;      getFunctionName(pExpr, &zId, &nId);      pDef = sqliteFindFunction(pParse->db, zId, nId, nExpr, 0);      assert( pDef!=0 );      nExpr = sqliteExprCodeExprList(pParse, pList, pDef->includeTypes);      sqliteVdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_POINTER);      break;    }    case TK_SELECT: {      sqliteVdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);      break;    }    case TK_IN: {      int addr;      sqliteVdbeAddOp(v, OP_Integer, 1, 0);      sqliteExprCode(pParse, pExpr->pLeft);      addr = sqliteVdbeCurrentAddr(v);      sqliteVdbeAddOp(v, OP_NotNull, -1, addr+4);      sqliteVdbeAddOp(v, OP_Pop, 2, 0);      sqliteVdbeAddOp(v, OP_String, 0, 0);      sqliteVdbeAddOp(v, OP_Goto, 0, addr+6);      if( pExpr->pSelect ){        sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, addr+6);      }else{        sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, addr+6);      }      sqliteVdbeAddOp(v, OP_AddImm, -1, 0);      break;    }    case TK_BETWEEN: {      sqliteExprCode(pParse, pExpr->pLeft);      sqliteVdbeAddOp(v, OP_Dup, 0, 0);      sqliteExprCode(pParse, pExpr->pList->a[0].pExpr);      sqliteVdbeAddOp(v, OP_Ge, 0, 0);      sqliteVdbeAddOp(v, OP_Pull, 1, 0);      sqliteExprCode(pParse, pExpr->pList->a[1].pExpr);      sqliteVdbeAddOp(v, OP_Le, 0, 0);      sqliteVdbeAddOp(v, OP_And, 0, 0);      break;    }    case TK_UPLUS:    case TK_AS: {      sqliteExprCode(pParse, pExpr->pLeft);      break;    }    case TK_CASE: {      int expr_end_label;      int jumpInst;      int addr;      int nExpr;      int i;      assert(pExpr->pList);      assert((pExpr->pList->nExpr % 2) == 0);      assert(pExpr->pList->nExpr > 0);      nExpr = pExpr->pList->nExpr;      expr_end_label = sqliteVdbeMakeLabel(v);      if( pExpr->pLeft ){        sqliteExprCode(pParse, pExpr->pLeft);      }      for(i=0; i<nExpr; i=i+2){        sqliteExprCode(pParse, pExpr->pList->a[i].pExpr);        if( pExpr->pLeft ){          sqliteVdbeAddOp(v, OP_Dup, 1, 1);          jumpInst = sqliteVdbeAddOp(v, OP_Ne, 1, 0);          sqliteVdbeAddOp(v, OP_Pop, 1, 0);        }else{          jumpInst = sqliteVdbeAddOp(v, OP_IfNot, 1, 0);        }        sqliteExprCode(pParse, pExpr->pList->a[i+1].pExpr);        sqliteVdbeAddOp(v, OP_Goto, 0, expr_end_label);        addr = sqliteVdbeCurrentAddr(v);        sqliteVdbeChangeP2(v, jumpInst, addr);      }      if( pExpr->pLeft ){        sqliteVdbeAddOp(v, OP_Pop, 1, 0);      }      if( pExpr->pRight ){        sqliteExprCode(pParse, pExpr->pRight);      }else{        sqliteVdbeAddOp(v, OP_String, 0, 0);      }      sqliteVdbeResolveLabel(v, expr_end_label);      break;    }    case TK_RAISE: {      if( !pParse->trigStack ){        sqliteErrorMsg(pParse,                       "RAISE() may only be used within a trigger-program");        pParse->nErr++;	return;      }      if( pExpr->iColumn == OE_Rollback ||	  pExpr->iColumn == OE_Abort ||	  pExpr->iColumn == OE_Fail ){

⌨️ 快捷键说明

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