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

📄 vdbe.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
** functions.**** The interface used by the implementation of the aforementioned functions** to retrieve the collation sequence set by this opcode is not available** publicly, only to user functions defined in func.c.*/case OP_CollSeq: {  assert( pOp->p4type==P4_COLLSEQ );  break;}/* Opcode: Function P1 P2 P3 P4 P5**** Invoke a user function (P4 is a pointer to a Function structure that** defines the function) with P5 arguments taken from register P2 and** successors.  The result of the function is stored in register P3.** Register P3 must not be one of the function inputs.**** P1 is a 32-bit bitmask indicating whether or not each argument to the ** function was determined to be constant at compile time. If the first** argument was constant then bit 0 of P1 is set. This is used to determine** whether meta data associated with a user function argument using the** sqlite3_set_auxdata() API may be safely retained until the next** invocation of this opcode.**** See also: AggStep and AggFinal*/case OP_Function: {  int i;  Mem *pArg;  sqlite3_context ctx;  sqlite3_value **apVal;  int n = pOp->p5;  apVal = p->apArg;  assert( apVal || n==0 );  assert( n==0 || (pOp->p2>0 && pOp->p2+n<=p->nMem) );  assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );  pArg = &p->aMem[pOp->p2];  for(i=0; i<n; i++, pArg++){    apVal[i] = pArg;    storeTypeInfo(pArg, encoding);    REGISTER_TRACE(pOp->p2, pArg);  }  assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC );  if( pOp->p4type==P4_FUNCDEF ){    ctx.pFunc = pOp->p4.pFunc;    ctx.pVdbeFunc = 0;  }else{    ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;    ctx.pFunc = ctx.pVdbeFunc->pFunc;  }  assert( pOp->p3>0 && pOp->p3<=p->nMem );  pOut = &p->aMem[pOp->p3];  ctx.s.flags = MEM_Null;  ctx.s.db = db;  ctx.s.xDel = 0;  ctx.s.zMalloc = 0;  /* The output cell may already have a buffer allocated. Move  ** the pointer to ctx.s so in case the user-function can use  ** the already allocated buffer instead of allocating a new one.  */  sqlite3VdbeMemMove(&ctx.s, pOut);  MemSetTypeFlag(&ctx.s, MEM_Null);  ctx.isError = 0;  if( ctx.pFunc->needCollSeq ){    assert( pOp>p->aOp );    assert( pOp[-1].p4type==P4_COLLSEQ );    assert( pOp[-1].opcode==OP_CollSeq );    ctx.pColl = pOp[-1].p4.pColl;  }  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;  (*ctx.pFunc->xFunc)(&ctx, n, apVal);  if( sqlite3SafetyOn(db) ){    sqlite3VdbeMemRelease(&ctx.s);    goto abort_due_to_misuse;  }  if( db->mallocFailed ){    /* Even though a malloc() has failed, the implementation of the    ** user function may have called an sqlite3_result_XXX() function    ** to return a value. The following call releases any resources    ** associated with such a value.    **    ** Note: Maybe MemRelease() should be called if sqlite3SafetyOn()    ** fails also (the if(...) statement above). But if people are    ** misusing sqlite, they have bigger problems than a leaked value.    */    sqlite3VdbeMemRelease(&ctx.s);    goto no_mem;  }  /* If any auxiliary 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->p4.pVdbeFunc = ctx.pVdbeFunc;    pOp->p4type = P4_VDBEFUNC;  }  /* If the function returned an error, throw an exception */  if( ctx.isError ){    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));    rc = ctx.isError;  }  /* Copy the result of the function into register P3 */  sqlite3VdbeChangeEncoding(&ctx.s, encoding);  sqlite3VdbeMemMove(pOut, &ctx.s);  if( sqlite3VdbeMemTooBig(pOut) ){    goto too_big;  }  REGISTER_TRACE(pOp->p3, pOut);  UPDATE_MAX_BLOBSIZE(pOut);  break;}/* Opcode: BitAnd P1 P2 P3 * ***** Take the bit-wise AND of the values in register P1 and P2 and** store the result in register P3.** If either input is NULL, the result is NULL.*//* Opcode: BitOr P1 P2 P3 * ***** Take the bit-wise OR of the values in register P1 and P2 and** store the result in register P3.** If either input is NULL, the result is NULL.*//* Opcode: ShiftLeft P1 P2 P3 * ***** Shift the integer value in register P2 to the left by the** number of bits specified by the integer in regiser P1.** Store the result in register P3.** If either input is NULL, the result is NULL.*//* Opcode: ShiftRight P1 P2 P3 * ***** Shift the integer value in register P2 to the right by the** number of bits specified by the integer in register P1.** Store the result in register P3.** If either input is NULL, the result is NULL.*/case OP_BitAnd:                 /* same as TK_BITAND, in1, in2, out3 */case OP_BitOr:                  /* same as TK_BITOR, in1, in2, out3 */case OP_ShiftLeft:              /* same as TK_LSHIFT, in1, in2, out3 */case OP_ShiftRight: {           /* same as TK_RSHIFT, in1, in2, out3 */  i64 a, b;  if( (pIn1->flags | pIn2->flags) & MEM_Null ){    sqlite3VdbeMemSetNull(pOut);    break;  }  a = sqlite3VdbeIntValue(pIn2);  b = sqlite3VdbeIntValue(pIn1);  switch( pOp->opcode ){    case OP_BitAnd:      a &= b;     break;    case OP_BitOr:       a |= b;     break;    case OP_ShiftLeft:   a <<= b;    break;    default:  assert( pOp->opcode==OP_ShiftRight );                         a >>= b;    break;  }  pOut->u.i = a;  MemSetTypeFlag(pOut, MEM_Int);  break;}/* Opcode: AddImm  P1 P2 * * *** ** Add the constant P2 to the value in register P1.** The result is always an integer.**** To force any register to be an integer, just add 0.*/case OP_AddImm: {            /* in1 */  sqlite3VdbeMemIntegerify(pIn1);  pIn1->u.i += pOp->p2;  break;}/* Opcode: ForceInt P1 P2 P3 * ***** Convert value in register P1 into an integer.  If the value ** in P1 is not numeric (meaning that is is a NULL or a string that** does not look like an integer or floating point number) then** jump to P2.  If the value in P1 is numeric then** convert it into the least integer that is greater than or equal to its** current value if P3==0, or to the least integer that is strictly** greater than its current value if P3==1.*/case OP_ForceInt: {            /* jump, in1 */  i64 v;  applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);  if( (pIn1->flags & (MEM_Int|MEM_Real))==0 ){    pc = pOp->p2 - 1;    break;  }  if( pIn1->flags & MEM_Int ){    v = pIn1->u.i + (pOp->p3!=0);  }else{    assert( pIn1->flags & MEM_Real );    v = (sqlite3_int64)pIn1->r;    if( pIn1->r>(double)v ) v++;    if( pOp->p3 && pIn1->r==(double)v ) v++;  }  pIn1->u.i = v;  MemSetTypeFlag(pIn1, MEM_Int);  break;}/* Opcode: MustBeInt P1 P2 * * *** ** Force the value in register P1 to be an integer.  If the value** in P1 is not an integer and cannot be converted into an integer** without data loss, then jump immediately to P2, or if P2==0** raise an SQLITE_MISMATCH exception.*/case OP_MustBeInt: {            /* jump, in1 */  applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);  if( (pIn1->flags & MEM_Int)==0 ){    if( pOp->p2==0 ){      rc = SQLITE_MISMATCH;      goto abort_due_to_error;    }else{      pc = pOp->p2 - 1;    }  }else{    MemSetTypeFlag(pIn1, MEM_Int);  }  break;}/* Opcode: RealAffinity P1 * * * ***** If register P1 holds 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: {                  /* in1 */  if( pIn1->flags & MEM_Int ){    sqlite3VdbeMemRealify(pIn1);  }  break;}#ifndef SQLITE_OMIT_CAST/* Opcode: ToText P1 * * * ***** Force the value in register P1 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, in1 */  if( pIn1->flags & MEM_Null ) break;  assert( MEM_Str==(MEM_Blob>>3) );  pIn1->flags |= (pIn1->flags&MEM_Blob)>>3;  applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);  rc = ExpandBlob(pIn1);  assert( pIn1->flags & MEM_Str || db->mallocFailed );  pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob);  UPDATE_MAX_BLOBSIZE(pIn1);  break;}/* Opcode: ToBlob P1 * * * ***** Force the value in register P1 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, in1 */  if( pIn1->flags & MEM_Null ) break;  if( (pIn1->flags & MEM_Blob)==0 ){    applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);    assert( pIn1->flags & MEM_Str || db->mallocFailed );  }  MemSetTypeFlag(pIn1, MEM_Blob);  UPDATE_MAX_BLOBSIZE(pIn1);  break;}/* Opcode: ToNumeric P1 * * * ***** Force the value in register P1 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, in1 */  if( (pIn1->flags & (MEM_Null|MEM_Int|MEM_Real))==0 ){    sqlite3VdbeMemNumerify(pIn1);  }  break;}#endif /* SQLITE_OMIT_CAST *//* Opcode: ToInt P1 * * * ***** Force the value in register P1 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, in1 */  if( (pIn1->flags & MEM_Null)==0 ){    sqlite3VdbeMemIntegerify(pIn1);  }  break;}#ifndef SQLITE_OMIT_CAST/* Opcode: ToReal P1 * * * ***** Force the value in register P1 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.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, in1 */  if( (pIn1->flags & MEM_Null)==0 ){    sqlite3VdbeMemRealify(pIn1);  }  break;}#endif /* SQLITE_OMIT_CAST *//* Opcode: Lt P1 P2 P3 P4 P5**** Compare the values in register P1 and P3.  If reg(P3)<reg(P1) then** jump to address P2.  **** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or** reg(P3) is NULL then take the jump.  If the SQLITE_JUMPIFNULL ** bit is clear then fall thru if either operand is NULL.**** The SQLITE_AFF_MASK portion of P5 must be an affinity character -** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made ** to coerce both inputs according to this affinity before the** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric** affinity is used. Note that the affinity conversions are stored** back into the input registers P1 and P3.  So this opcode can cause** persistent changes to registers P1 and P3.**** Once any conversions have taken place, and neither value is NULL, ** the values are compared. If both values are blobs then memcmp() is** used to determine the results of the comparison.  If both values** are text, then the appropriate collating function specified in** P4 is  used to do the comparison.  If P4 is not specified then** memcmp() is used to compare text string.  If both values are** numeric, then a numeric comparison is used. If the two values** are of different types, then numbers are considered less than** strings and strings are considered less than blobs.**** If the SQLITE_STOREP2 bit of P5 is set, then do not jump.  Instead,** store a boolean result (either 0, or 1, or NULL) in register P2.*//* Opcode: Ne P1 P2 P3 P4 P5**** This works just like the Lt opcode except that the jump is taken if** the operands in registers P1 and P3 are not equal.  See the Lt opcode for** additional information.*//* Opcode: Eq P1 P2 P3 P4 P5**** This works just like the Lt opcode except that the jump is taken if** the operands in registers P1 and P3 are equal.** See the Lt opcode for additional information.*//* Opcode: Le P1 P2 P3 P4 P5**** This works just like the Lt opcode except that the jump is taken if** the content of register P3 is less than or equal to the content of** register P1.  See the Lt opcode for additional information.*//* Opcode: Gt P1 P2 P3 P4 P5**** This works just like the Lt opcode except that the jump is taken if** the content of register P3 is greater than the content of** register P1.  See the Lt opcode for additional information.*//* Opcode: Ge P1 P2 P3 P4 P5**** This works just like the Lt opcode except that the jump is taken if** the content of register P3 is greater than or equal to the content of** register P1.  See the Lt opcode for additional information.*/case OP_Eq:               /* same as TK_EQ, jump, in1, in3 */case OP_Ne:               /* same as TK_NE, jump, in1, in3 */case OP_Lt:               /* same as TK_LT, jump, in1, in3 */case OP_Le:               /* same as TK_LE, jump, in1, in3 */case OP_Gt:               /* same as TK_GT, jump, in1, in3 */case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */  int flags;  int res;  char affinity;  flags = pIn1->flags|pIn3->flags;  if( flags&MEM_Null ){

⌨️ 快捷键说明

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