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

📄 expr.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 5 页
字号:
}#endif /* SQLITE_OMIT_SUBQUERY *//*** Generate an instruction that will put the integer describe by** text z[0..n-1] on the stack.*/static void codeInteger(Vdbe *v, const char *z, int n){  assert( z || sqlite3MallocFailed() );  if( z ){    int i;    if( sqlite3GetInt32(z, &i) ){      sqlite3VdbeAddOp(v, OP_Integer, i, 0);    }else if( sqlite3FitsIn64Bits(z) ){      sqlite3VdbeOp3(v, OP_Int64, 0, 0, z, n);    }else{      sqlite3VdbeOp3(v, OP_Real, 0, 0, z, n);    }  }}/*** Generate code that will extract the iColumn-th column from** table pTab and push that column value on the stack.  There** is an open cursor to pTab in iTable.  If iColumn<0 then** code is generated that extracts the rowid.*/void sqlite3ExprCodeGetColumn(Vdbe *v, Table *pTab, int iColumn, int iTable){  if( iColumn<0 ){    int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid;    sqlite3VdbeAddOp(v, op, iTable, 0);  }else if( pTab==0 ){    sqlite3VdbeAddOp(v, OP_Column, iTable, iColumn);  }else{    int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;    sqlite3VdbeAddOp(v, op, iTable, iColumn);    sqlite3ColumnDefault(v, pTab, iColumn);#ifndef SQLITE_OMIT_FLOATING_POINT    if( pTab->aCol[iColumn].affinity==SQLITE_AFF_REAL ){      sqlite3VdbeAddOp(v, OP_RealAffinity, 0, 0);    }#endif  }}/*** Generate code into the current Vdbe to evaluate the given** expression and leave the result on the top of stack.**** This code depends on the fact that certain token values (ex: TK_EQ)** are the same as opcode values (ex: OP_Eq) that implement the corresponding** operation.  Special comments in vdbe.c and the mkopcodeh.awk script in** the make process cause these values to align.  Assert()s in the code** below verify that the numbers are aligned correctly.*/void sqlite3ExprCode(Parse *pParse, Expr *pExpr){  Vdbe *v = pParse->pVdbe;  int op;  int stackChng = 1;    /* Amount of change to stack depth */  if( v==0 ) return;  if( pExpr==0 ){    sqlite3VdbeAddOp(v, OP_Null, 0, 0);    return;  }  op = pExpr->op;  switch( op ){    case TK_AGG_COLUMN: {      AggInfo *pAggInfo = pExpr->pAggInfo;      struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];      if( !pAggInfo->directMode ){        sqlite3VdbeAddOp(v, OP_MemLoad, pCol->iMem, 0);        break;      }else if( pAggInfo->useSortingIdx ){        sqlite3VdbeAddOp(v, OP_Column, pAggInfo->sortingIdx,                              pCol->iSorterColumn);        break;      }      /* Otherwise, fall thru into the TK_COLUMN case */    }    case TK_COLUMN: {      if( pExpr->iTable<0 ){        /* This only happens when coding check constraints */        assert( pParse->ckOffset>0 );        sqlite3VdbeAddOp(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1);      }else{        sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable);      }      break;    }    case TK_INTEGER: {      codeInteger(v, (char*)pExpr->token.z, pExpr->token.n);      break;    }    case TK_FLOAT:    case TK_STRING: {      assert( TK_FLOAT==OP_Real );      assert( TK_STRING==OP_String8 );      sqlite3DequoteExpr(pExpr);      sqlite3VdbeOp3(v, op, 0, 0, (char*)pExpr->token.z, pExpr->token.n);      break;    }    case TK_NULL: {      sqlite3VdbeAddOp(v, OP_Null, 0, 0);      break;    }#ifndef SQLITE_OMIT_BLOB_LITERAL    case TK_BLOB: {      int n;      const char *z;      assert( TK_BLOB==OP_HexBlob );      n = pExpr->token.n - 3;      z = (char*)pExpr->token.z + 2;      assert( n>=0 );      if( n==0 ){        z = "";      }      sqlite3VdbeOp3(v, op, 0, 0, z, n);      break;    }#endif    case TK_VARIABLE: {      sqlite3VdbeAddOp(v, OP_Variable, pExpr->iTable, 0);      if( pExpr->token.n>1 ){        sqlite3VdbeChangeP3(v, -1, (char*)pExpr->token.z, pExpr->token.n);      }      break;    }    case TK_REGISTER: {      sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iTable, 0);      break;    }#ifndef SQLITE_OMIT_CAST    case TK_CAST: {      /* Expressions of the form:   CAST(pLeft AS token) */      int aff, to_op;      sqlite3ExprCode(pParse, pExpr->pLeft);      aff = sqlite3AffinityType(&pExpr->token);      to_op = aff - SQLITE_AFF_TEXT + OP_ToText;      assert( to_op==OP_ToText    || aff!=SQLITE_AFF_TEXT    );      assert( to_op==OP_ToBlob    || aff!=SQLITE_AFF_NONE    );      assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC );      assert( to_op==OP_ToInt     || aff!=SQLITE_AFF_INTEGER );      assert( to_op==OP_ToReal    || aff!=SQLITE_AFF_REAL    );      sqlite3VdbeAddOp(v, to_op, 0, 0);      stackChng = 0;      break;    }#endif /* SQLITE_OMIT_CAST */    case TK_LT:    case TK_LE:    case TK_GT:    case TK_GE:    case TK_NE:    case TK_EQ: {      assert( TK_LT==OP_Lt );      assert( TK_LE==OP_Le );      assert( TK_GT==OP_Gt );      assert( TK_GE==OP_Ge );      assert( TK_EQ==OP_Eq );      assert( TK_NE==OP_Ne );      sqlite3ExprCode(pParse, pExpr->pLeft);      sqlite3ExprCode(pParse, pExpr->pRight);      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0);      stackChng = -1;      break;    }    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:    case TK_LSHIFT:    case TK_RSHIFT:     case TK_CONCAT: {      assert( TK_AND==OP_And );      assert( TK_OR==OP_Or );      assert( TK_PLUS==OP_Add );      assert( TK_MINUS==OP_Subtract );      assert( TK_REM==OP_Remainder );      assert( TK_BITAND==OP_BitAnd );      assert( TK_BITOR==OP_BitOr );      assert( TK_SLASH==OP_Divide );      assert( TK_LSHIFT==OP_ShiftLeft );      assert( TK_RSHIFT==OP_ShiftRight );      assert( TK_CONCAT==OP_Concat );      sqlite3ExprCode(pParse, pExpr->pLeft);      sqlite3ExprCode(pParse, pExpr->pRight);      sqlite3VdbeAddOp(v, op, 0, 0);      stackChng = -1;      break;    }    case TK_UMINUS: {      Expr *pLeft = pExpr->pLeft;      assert( pLeft );      if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){        Token *p = &pLeft->token;        char *z = sqlite3MPrintf("-%.*s", p->n, p->z);        if( pLeft->op==TK_FLOAT ){          sqlite3VdbeOp3(v, OP_Real, 0, 0, z, p->n+1);        }else{          codeInteger(v, z, p->n+1);        }        sqliteFree(z);        break;      }      /* Fall through into TK_NOT */    }    case TK_BITNOT:    case TK_NOT: {      assert( TK_BITNOT==OP_BitNot );      assert( TK_NOT==OP_Not );      sqlite3ExprCode(pParse, pExpr->pLeft);      sqlite3VdbeAddOp(v, op, 0, 0);      stackChng = 0;      break;    }    case TK_ISNULL:    case TK_NOTNULL: {      int dest;      assert( TK_ISNULL==OP_IsNull );      assert( TK_NOTNULL==OP_NotNull );      sqlite3VdbeAddOp(v, OP_Integer, 1, 0);      sqlite3ExprCode(pParse, pExpr->pLeft);      dest = sqlite3VdbeCurrentAddr(v) + 2;      sqlite3VdbeAddOp(v, op, 1, dest);      sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);      stackChng = 0;      break;    }    case TK_AGG_FUNCTION: {      AggInfo *pInfo = pExpr->pAggInfo;      if( pInfo==0 ){        sqlite3ErrorMsg(pParse, "misuse of aggregate: %T",            &pExpr->span);      }else{        sqlite3VdbeAddOp(v, OP_MemLoad, pInfo->aFunc[pExpr->iAgg].iMem, 0);      }      break;    }    case TK_CONST_FUNC:    case TK_FUNCTION: {      ExprList *pList = pExpr->pList;      int nExpr = pList ? pList->nExpr : 0;      FuncDef *pDef;      int nId;      const char *zId;      int constMask = 0;      int i;      u8 enc = ENC(pParse->db);      CollSeq *pColl = 0;      zId = (char*)pExpr->token.z;      nId = pExpr->token.n;      pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0);      assert( pDef!=0 );      nExpr = sqlite3ExprCodeExprList(pParse, pList);#ifndef SQLITE_OMIT_VIRTUALTABLE      /* Possibly overload the function if the first argument is      ** a virtual table column.      **      ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the      ** second argument, not the first, as the argument to test to      ** see if it is a column in a virtual table.  This is done because      ** the left operand of infix functions (the operand we want to      ** control overloading) ends up as the second argument to the      ** function.  The expression "A glob B" is equivalent to       ** "glob(B,A).  We want to use the A in "A glob B" to test      ** for function overloading.  But we use the B term in "glob(B,A)".      */      if( nExpr>=2 && (pExpr->flags & EP_InfixFunc) ){        pDef = sqlite3VtabOverloadFunction(pDef, nExpr, pList->a[1].pExpr);      }else if( nExpr>0 ){        pDef = sqlite3VtabOverloadFunction(pDef, nExpr, pList->a[0].pExpr);      }#endif      for(i=0; i<nExpr && i<32; i++){        if( sqlite3ExprIsConstant(pList->a[i].pExpr) ){          constMask |= (1<<i);        }        if( pDef->needCollSeq && !pColl ){          pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);        }      }      if( pDef->needCollSeq ){        if( !pColl ) pColl = pParse->db->pDfltColl;         sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);      }      sqlite3VdbeOp3(v, OP_Function, constMask, nExpr, (char*)pDef, P3_FUNCDEF);      stackChng = 1-nExpr;      break;    }#ifndef SQLITE_OMIT_SUBQUERY    case TK_EXISTS:    case TK_SELECT: {      if( pExpr->iColumn==0 ){        sqlite3CodeSubselect(pParse, pExpr);      }      sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);      VdbeComment((v, "# load subquery result"));      break;    }    case TK_IN: {      int addr;      char affinity;      int ckOffset = pParse->ckOffset;      sqlite3CodeSubselect(pParse, pExpr);      /* Figure out the affinity to use to create a key from the results      ** of the expression. affinityStr stores a static string suitable for      ** P3 of OP_MakeRecord.      */      affinity = comparisonAffinity(pExpr);      sqlite3VdbeAddOp(v, OP_Integer, 1, 0);      pParse->ckOffset = (ckOffset ? (ckOffset+1) : 0);      /* Code the <expr> from "<expr> IN (...)". The temporary table      ** pExpr->iTable contains the values that make up the (...) set.      */      sqlite3ExprCode(pParse, pExpr->pLeft);      addr = sqlite3VdbeCurrentAddr(v);      sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+4);            /* addr + 0 */      sqlite3VdbeAddOp(v, OP_Pop, 2, 0);      sqlite3VdbeAddOp(v, OP_Null, 0, 0);      sqlite3VdbeAddOp(v, OP_Goto, 0, addr+7);      sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);   /* addr + 4 */      sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7);      sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);                  /* addr + 6 */      break;    }#endif    case TK_BETWEEN: {      Expr *pLeft = pExpr->pLeft;      struct ExprList_item *pLItem = pExpr->pList->a;      Expr *pRight = pLItem->pExpr;      sqlite3ExprCode(pParse, pLeft);      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);      sqlite3ExprCode(pParse, pRight);      codeCompare(pParse, pLeft, pRight, OP_Ge, 0, 0);      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);      pLItem++;      pRight = pLItem->pExpr;      sqlite3ExprCode(pParse, pRight);      codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0);      sqlite3VdbeAddOp(v, OP_And, 0, 0);      break;    }    case TK_UPLUS: {      sqlite3ExprCode(pParse, pExpr->pLeft);      stackChng = 0;      break;    }    case TK_CASE: {      int expr_end_label;      int jumpInst;      int nExpr;      int i;      ExprList *pEList;      struct ExprList_item *aListelem;      assert(pExpr->pList);      assert((pExpr->pList->nExpr % 2) == 0);      assert(pExpr->pList->nExpr > 0);      pEList = pExpr->pList;      aListelem = pEList->a;      nExpr = pEList->nExpr;      expr_end_label = sqlite3VdbeMakeLabel(v);      if( pExpr->pLeft ){        sqlite3ExprCode(pParse, pExpr->pLeft);      }      for(i=0; i<nExpr; i=i+2){        sqlite3ExprCode(pParse, aListelem[i].pExpr);        if( pExpr->pLeft ){          sqlite3VdbeAddOp(v, OP_Dup, 1, 1);          jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr,                                 OP_Ne, 0, 1);          sqlite3VdbeAddOp(v, OP_Pop, 1, 0);        }else{          jumpInst = sqlite3VdbeAddOp(v, OP_IfNot, 1, 0);        }        sqlite3ExprCode(pParse, aListelem[i+1].pExpr);        sqlite3VdbeAddOp(v, OP_Goto, 0, expr_end_label);        sqlite3VdbeJumpHere(v, jumpInst);      }      if( pExpr->pLeft ){        sqlite3VdbeAddOp(v, OP_Pop, 1, 0);      }      if( pExpr->pRight ){        sqlite3ExprCode(pParse, pExpr->pRight);      }else{        sqlite3VdbeAddOp(v, OP_Null, 0, 0);      }      sqlite3VdbeResolveLabel(v, expr_end_label);      break;    }#ifndef SQLITE_OMIT_TRIGGER    case TK_RAISE: {      if( !pParse->trigStack ){        sqlite3ErrorMsg(pParse,                       "RAISE() may only be used within a trigger-program");	return;      }      if( pExpr->iColumn!=OE_Ignore ){         assert( pExpr->iColumn==OE_Rollback ||                 pExpr->iCo

⌨️ 快捷键说明

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