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

📄 vdbe.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 5 页
字号:
  apVal = p->apArg;  assert( apVal || n==0 );  pArg = &pTos[1-n];  for(i=0; i<n; i++, pArg++){    apVal[i] = pArg;    storeTypeInfo(pArg, encoding);  }  assert( pOp->p3type==P3_FUNCDEF || pOp->p3type==P3_VDBEFUNC );  if( pOp->p3type==P3_FUNCDEF ){    ctx.pFunc = (FuncDef*)pOp->p3;    ctx.pVdbeFunc = 0;  }else{    ctx.pVdbeFunc = (VdbeFunc*)pOp->p3;    ctx.pFunc = ctx.pVdbeFunc->pFunc;  }  ctx.s.flags = MEM_Null;  ctx.s.z = 0;  ctx.s.xDel = 0;  ctx.isError = 0;  if( ctx.pFunc->needCollSeq ){    assert( pOp>p->aOp );    assert( pOp[-1].p3type==P3_COLLSEQ );    assert( pOp[-1].opcode==OP_CollSeq );    ctx.pColl = (CollSeq *)pOp[-1].p3;  }  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;  (*ctx.pFunc->xFunc)(&ctx, n, apVal);  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;  if( sqlite3MallocFailed() ) goto no_mem;  popStack(&pTos, n);  /* If any auxilary data functions have been called by this user function,  ** immediately call the destructor for any non-static values.  */  if( ctx.pVdbeFunc ){    sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p1);    pOp->p3 = (char *)ctx.pVdbeFunc;    pOp->p3type = P3_VDBEFUNC;  }  /* If the function returned an error, throw an exception */  if( ctx.isError ){    sqlite3SetString(&p->zErrMsg, sqlite3_value_text(&ctx.s), (char*)0);    rc = SQLITE_ERROR;  }  /* Copy the result of the function to the top of the stack */  sqlite3VdbeChangeEncoding(&ctx.s, encoding);  pTos++;  pTos->flags = 0;  sqlite3VdbeMemMove(pTos, &ctx.s);  if( sqlite3VdbeMemTooBig(pTos) ){    goto too_big;  }  break;}/* Opcode: BitAnd * * ***** Pop the top two elements from the stack.  Convert both elements** to integers.  Push back onto the stack the bit-wise AND of the** two elements.** If either operand is NULL, the result is NULL.*//* Opcode: BitOr * * ***** Pop the top two elements from the stack.  Convert both elements** to integers.  Push back onto the stack the bit-wise OR of the** two elements.** If either operand is NULL, the result is NULL.*//* Opcode: ShiftLeft * * ***** Pop the top two elements from the stack.  Convert both elements** to integers.  Push back onto the stack the second element shifted** left by N bits where N is the top element on the stack.** If either operand is NULL, the result is NULL.*//* Opcode: ShiftRight * * ***** Pop the top two elements from the stack.  Convert both elements** to integers.  Push back onto the stack the second element shifted** right by N bits where N is the top element on the stack.** If either operand is NULL, the result is NULL.*/case OP_BitAnd:                 /* same as TK_BITAND, no-push */case OP_BitOr:                  /* same as TK_BITOR, no-push */case OP_ShiftLeft:              /* same as TK_LSHIFT, no-push */case OP_ShiftRight: {           /* same as TK_RSHIFT, no-push */  Mem *pNos = &pTos[-1];  i64 a, b;  assert( pNos>=p->aStack );  if( (pTos->flags | pNos->flags) & MEM_Null ){    popStack(&pTos, 2);    pTos++;    pTos->flags = MEM_Null;    break;  }  a = sqlite3VdbeIntValue(pNos);  b = sqlite3VdbeIntValue(pTos);  switch( pOp->opcode ){    case OP_BitAnd:      a &= b;     break;    case OP_BitOr:       a |= b;     break;    case OP_ShiftLeft:   a <<= b;    break;    case OP_ShiftRight:  a >>= b;    break;    default:   /* CANT HAPPEN */     break;  }  Release(pTos);  pTos--;  Release(pTos);  pTos->u.i = a;  pTos->flags = MEM_Int;  break;}/* Opcode: AddImm  P1 * *** ** Add the value P1 to whatever is on top of the stack.  The result** is always an integer.**** To force the top of the stack to be an integer, just add 0.*/case OP_AddImm: {            /* no-push */  assert( pTos>=p->aStack );  sqlite3VdbeMemIntegerify(pTos);  pTos->u.i += pOp->p1;  break;}/* Opcode: ForceInt P1 P2 ***** Convert the top of the stack into an integer.  If the current top of** the stack is not numeric (meaning that is is a NULL or a string that** does not look like an integer or floating point number) then pop the** stack and jump to P2.  If the top of the stack is numeric then** convert it into the least integer that is greater than or equal to its** current value if P1==0, or to the least integer that is strictly** greater than its current value if P1==1.*/case OP_ForceInt: {            /* no-push */  i64 v;  assert( pTos>=p->aStack );  applyAffinity(pTos, SQLITE_AFF_NUMERIC, encoding);  if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){    Release(pTos);    pTos--;    pc = pOp->p2 - 1;    break;  }  if( pTos->flags & MEM_Int ){    v = pTos->u.i + (pOp->p1!=0);  }else{    /* FIX ME:  should this not be assert( pTos->flags & MEM_Real ) ??? */    sqlite3VdbeMemRealify(pTos);    v = (int)pTos->r;    if( pTos->r>(double)v ) v++;    if( pOp->p1 && pTos->r==(double)v ) v++;  }  Release(pTos);  pTos->u.i = v;  pTos->flags = MEM_Int;  break;}/* Opcode: MustBeInt P1 P2 *** ** Force the top of the stack to be an integer.  If the top of the** stack is not an integer and cannot be converted into an integer** with out data loss, then jump immediately to P2, or if P2==0** raise an SQLITE_MISMATCH exception.**** If the top of the stack is not an integer and P2 is not zero and** P1 is 1, then the stack is popped.  In all other cases, the depth** of the stack is unchanged.*/case OP_MustBeInt: {            /* no-push */  assert( pTos>=p->aStack );  applyAffinity(pTos, SQLITE_AFF_NUMERIC, encoding);  if( (pTos->flags & MEM_Int)==0 ){    if( pOp->p2==0 ){      rc = SQLITE_MISMATCH;      goto abort_due_to_error;    }else{      if( pOp->p1 ) popStack(&pTos, 1);      pc = pOp->p2 - 1;    }  }else{    Release(pTos);    pTos->flags = MEM_Int;  }  break;}/* Opcode: RealAffinity * * ***** If the top of the stack is an integer, convert it to a real value.**** This opcode is used when extracting information from a column that** has REAL affinity.  Such column values may still be stored as** integers, for space efficiency, but after extraction we want them** to have only a real value.*/case OP_RealAffinity: {                  /* no-push */  assert( pTos>=p->aStack );  if( pTos->flags & MEM_Int ){    sqlite3VdbeMemRealify(pTos);  }  break;}#ifndef SQLITE_OMIT_CAST/* Opcode: ToText * * ***** Force the value on the top of the stack to be text.** If the value is numeric, convert it to a string using the** equivalent of printf().  Blob values are unchanged and** are afterwards simply interpreted as text.**** A NULL value is not changed by this routine.  It remains NULL.*/case OP_ToText: {                  /* same as TK_TO_TEXT, no-push */  assert( pTos>=p->aStack );  if( pTos->flags & MEM_Null ) break;  assert( MEM_Str==(MEM_Blob>>3) );  pTos->flags |= (pTos->flags&MEM_Blob)>>3;  applyAffinity(pTos, SQLITE_AFF_TEXT, encoding);  rc = ExpandBlob(pTos);  assert( pTos->flags & MEM_Str );  pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Blob);  break;}/* Opcode: ToBlob * * ***** Force the value on the top of the stack to be a BLOB.** If the value is numeric, convert it to a string first.** Strings are simply reinterpreted as blobs with no change** to the underlying data.**** A NULL value is not changed by this routine.  It remains NULL.*/case OP_ToBlob: {                  /* same as TK_TO_BLOB, no-push */  assert( pTos>=p->aStack );  if( pTos->flags & MEM_Null ) break;  if( (pTos->flags & MEM_Blob)==0 ){    applyAffinity(pTos, SQLITE_AFF_TEXT, encoding);    assert( pTos->flags & MEM_Str );    pTos->flags |= MEM_Blob;  }  pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Str);  break;}/* Opcode: ToNumeric * * ***** Force the value on the top of the stack to be numeric (either an** integer or a floating-point number.)** If the value is text or blob, try to convert it to an using the** equivalent of atoi() or atof() and store 0 if no such conversion ** is possible.**** A NULL value is not changed by this routine.  It remains NULL.*/case OP_ToNumeric: {                  /* same as TK_TO_NUMERIC, no-push */  assert( pTos>=p->aStack );  if( (pTos->flags & (MEM_Null|MEM_Int|MEM_Real))==0 ){    sqlite3VdbeMemNumerify(pTos);  }  break;}#endif /* SQLITE_OMIT_CAST *//* Opcode: ToInt * * ***** Force the value on the top of the stack to be an integer.  If** The value is currently a real number, drop its fractional part.** If the value is text or blob, try to convert it to an integer using the** equivalent of atoi() and store 0 if no such conversion is possible.**** A NULL value is not changed by this routine.  It remains NULL.*/case OP_ToInt: {                  /* same as TK_TO_INT, no-push */  assert( pTos>=p->aStack );  if( (pTos->flags & MEM_Null)==0 ){    sqlite3VdbeMemIntegerify(pTos);  }  break;}#ifndef SQLITE_OMIT_CAST/* Opcode: ToReal * * ***** Force the value on the top of the stack to be a floating point number.** If The value is currently an integer, convert it.** If the value is text or blob, try to convert it to an integer using the** equivalent of atoi() and store 0 if no such conversion is possible.**** A NULL value is not changed by this routine.  It remains NULL.*/case OP_ToReal: {                  /* same as TK_TO_REAL, no-push */  assert( pTos>=p->aStack );  if( (pTos->flags & MEM_Null)==0 ){    sqlite3VdbeMemRealify(pTos);  }  break;}#endif /* SQLITE_OMIT_CAST *//* Opcode: Eq P1 P2 P3**** Pop the top two elements from the stack.  If they are equal, then** jump to instruction P2.  Otherwise, continue to the next instruction.**** If the 0x100 bit of P1 is true and either operand is NULL then take the** jump.  If the 0x100 bit of P1 is clear then fall thru if either operand** is NULL.**** If the 0x200 bit of P1 is set and either operand is NULL then** both operands are converted to integers prior to comparison.** NULL operands are converted to zero and non-NULL operands are** converted to 1.  Thus, for example, with 0x200 set,  NULL==NULL is true** whereas it would normally be NULL.  Similarly,  NULL==123 is false when** 0x200 is set but is NULL when the 0x200 bit of P1 is clear.**** The least significant byte of P1 (mask 0xff) must be an affinity character -** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made ** to coerce both values** according to the affinity before the comparison is made. If the byte is** 0x00, then numeric affinity is used.**** Once any conversions have taken place, and neither value is NULL, ** the values are compared. If both values are blobs, or both are text,** then memcmp() is used to determine the results of the comparison. If** both values are numeric, then a numeric comparison is used. If the** two values are of different types, then they are inequal.**** If P2 is zero, do not jump.  Instead, push an integer 1 onto the** stack if the jump would have been taken, or a 0 if not.  Push a** NULL if either operand was NULL.**** If P3 is not NULL it is a pointer to a collating sequence (a CollSeq** structure) that defines how to compare text.*//* Opcode: Ne P1 P2 P3**** This works just like the Eq opcode except that the jump is taken if** the operands from the stack are not equal.  See the Eq opcode for** additional information.*//* Opcode: Lt P1 P2 P3**** This works just like the Eq opcode except that the jump is taken if** the 2nd element down on the stack is less than the top of the stack.** See the Eq opcode for additional information.*//* Opcode: Le P1 P2 P3**** This works just like the Eq opcode except that the jump is taken if** the 2nd element down on the stack is less than or equal to the** top of the stack.  See the Eq opcode for additional information.*//* Opcode: Gt P1 P2 P3**** This works just like the Eq opcode except that the jump is taken if** the 2nd element down on the stack is greater than the top of the stack.** See the Eq opcode for additional information.*//* Opcode: Ge P1 P2 P3**** This works just like the Eq opcode except that the jump is taken if** the 2nd element down on the stack is greater than or equal to the** top of the stack.  See the Eq opcode for additional information.*/case OP_Eq:               /* same as TK_EQ, no-push */case OP_Ne:               /* same as TK_NE, no-push */case OP_Lt:               /* same as TK_LT, no-push */case OP_Le:               /* same as TK_LE, no-push */case OP_Gt:               /* same as TK_GT, no-push */case OP_Ge: {             /* same as TK_GE, no-push */  Mem *pNos;  int flags;  int res;  char affinity;  pNos = &pTos[-1];  flags = pTos->flags|pNos->flags;  /* If either value is a NULL P2 is not zero, take the jump if the least  ** significant byte of P1 is true. If P2 is zero, then push a NULL onto  ** the stack.  */  if( flags&MEM_Null ){    if( (pOp->p1 & 0x200)!=0 ){      /* The 0x200 bit of P1 means, roughly "do not treat NULL as the      ** magic SQL value it normally is - treat it as if it were another      ** integer".      **      ** With 0x200 set, if either operand is NULL then both operands      ** are converted to integers prior to being passed down into the      ** normal comparison logic below.  NULL operands are converted to      ** zero and non-NULL operands are converted to 1.  Thus, for example,      ** with 0x200 set,  NULL==NULL is true whereas it would normally      ** be NULL.  Similarly,  NULL!=123 is true.      */      sqlite3VdbeMemSetInt64(pTos, (pTos->flags & MEM_Null)==0);      sqlite3VdbeMemSetInt64(pNos, (pNos->flags & MEM_Null)==0);    }else{      /* If the 0x200 bit of P1 is clear and either operand is NULL then      ** the result is always NULL.  The jump is taken if the 0x100 bit      ** of P1 is set.      */      popStack(&pTos, 2);      if( pOp->p2 ){        if( pOp->p1 & 0x100 ){          pc = pOp->p2-1;        }

⌨️ 快捷键说明

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