📄 vdbemem.c
字号:
assert( pMem->z ); sqlite3Atoi64(pMem->z, &value); return value; }else{ return 0; }}/*** Return the best representation of pMem that we can get into a** double. If pMem is already a double or an integer, return its** value. If it is a string or blob, try to convert it to a double.** If it is a NULL, return 0.0.*/double sqlite3VdbeRealValue(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); if( pMem->flags & MEM_Real ){ return pMem->r; }else if( pMem->flags & MEM_Int ){ return (double)pMem->u.i; }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ double val = 0.0; pMem->flags |= MEM_Str; if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8) || sqlite3VdbeMemNulTerminate(pMem) ){ return 0.0; } assert( pMem->z ); sqlite3AtoF(pMem->z, &val); return val; }else{ return 0.0; }}/*** The MEM structure is already a MEM_Real. Try to also make it a** MEM_Int if we can.*/void sqlite3VdbeIntegerAffinity(Mem *pMem){ assert( pMem->flags & MEM_Real ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); pMem->u.i = doubleToInt64(pMem->r); if( pMem->r==(double)pMem->u.i ){ pMem->flags |= MEM_Int; }}/*** Convert pMem to type integer. Invalidate any prior representations.*/int sqlite3VdbeMemIntegerify(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); pMem->u.i = sqlite3VdbeIntValue(pMem); sqlite3VdbeMemRelease(pMem); pMem->flags = MEM_Int; return SQLITE_OK;}/*** Convert pMem so that it is of type MEM_Real.** Invalidate any prior representations.*/int sqlite3VdbeMemRealify(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); pMem->r = sqlite3VdbeRealValue(pMem); sqlite3VdbeMemRelease(pMem); pMem->flags = MEM_Real; return SQLITE_OK;}/*** Convert pMem so that it has types MEM_Real or MEM_Int or both.** Invalidate any prior representations.*/int sqlite3VdbeMemNumerify(Mem *pMem){ double r1, r2; i64 i; assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ); assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); r1 = sqlite3VdbeRealValue(pMem); i = doubleToInt64(r1); r2 = (double)i; if( r1==r2 ){ sqlite3VdbeMemIntegerify(pMem); }else{ pMem->r = r1; pMem->flags = MEM_Real; sqlite3VdbeMemRelease(pMem); } return SQLITE_OK;}/*** Delete any previous value and set the value stored in *pMem to NULL.*/void sqlite3VdbeMemSetNull(Mem *pMem){ sqlite3VdbeMemRelease(pMem); pMem->flags = MEM_Null; pMem->type = SQLITE_NULL; pMem->n = 0;}/*** Delete any previous value and set the value to be a BLOB of length** n containing all zeros.*/void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ sqlite3VdbeMemRelease(pMem); pMem->flags = MEM_Blob|MEM_Zero|MEM_Short; pMem->type = SQLITE_BLOB; pMem->n = 0; if( n<0 ) n = 0; pMem->u.i = n; pMem->z = pMem->zShort; pMem->enc = SQLITE_UTF8;}/*** Delete any previous value and set the value stored in *pMem to val,** manifest type INTEGER.*/void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ sqlite3VdbeMemRelease(pMem); pMem->u.i = val; pMem->flags = MEM_Int; pMem->type = SQLITE_INTEGER;}/*** Delete any previous value and set the value stored in *pMem to val,** manifest type REAL.*/void sqlite3VdbeMemSetDouble(Mem *pMem, double val){ if( sqlite3_isnan(val) ){ sqlite3VdbeMemSetNull(pMem); }else{ sqlite3VdbeMemRelease(pMem); pMem->r = val; pMem->flags = MEM_Real; pMem->type = SQLITE_FLOAT; }}/*** Return true if the Mem object contains a TEXT or BLOB that is** too large - whose size exceeds SQLITE_MAX_LENGTH.*/int sqlite3VdbeMemTooBig(Mem *p){ if( p->flags & (MEM_Str|MEM_Blob) ){ int n = p->n; if( p->flags & MEM_Zero ){ n += p->u.i; } return n>SQLITE_MAX_LENGTH; } return 0; }/*** Make an shallow copy of pFrom into pTo. Prior contents of** pTo are freed. The pFrom->z field is not duplicated. If** pFrom->z is used, then pTo->z points to the same thing as pFrom->z** and flags gets srcType (either MEM_Ephem or MEM_Static).*/void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ sqlite3VdbeMemRelease(pTo); memcpy(pTo, pFrom, sizeof(*pFrom)-sizeof(pFrom->zShort)); pTo->xDel = 0; if( pTo->flags & (MEM_Str|MEM_Blob) ){ pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short|MEM_Ephem); assert( srcType==MEM_Ephem || srcType==MEM_Static ); pTo->flags |= srcType; }}/*** Make a full copy of pFrom into pTo. Prior contents of pTo are** freed before the copy is made.*/int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ int rc; sqlite3VdbeMemShallowCopy(pTo, pFrom, MEM_Ephem); if( pTo->flags & MEM_Ephem ){ rc = sqlite3VdbeMemMakeWriteable(pTo); }else{ rc = SQLITE_OK; } return rc;}/*** Transfer the contents of pFrom to pTo. Any existing value in pTo is** freed. If pFrom contains ephemeral data, a copy is made.**** pFrom contains an SQL NULL when this routine returns.*/void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ assert( pFrom->db==0 || sqlite3_mutex_held(pFrom->db->mutex) ); assert( pTo->db==0 || sqlite3_mutex_held(pTo->db->mutex) ); assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db ); if( pTo->flags & MEM_Dyn ){ sqlite3VdbeMemRelease(pTo); } memcpy(pTo, pFrom, sizeof(Mem)); if( pFrom->flags & MEM_Short ){ pTo->z = pTo->zShort; } pFrom->flags = MEM_Null; pFrom->xDel = 0;}/*** Change the value of a Mem to be a string or a BLOB.*/int sqlite3VdbeMemSetStr( Mem *pMem, /* Memory cell to set to string value */ const char *z, /* String pointer */ int n, /* Bytes in string, or negative */ u8 enc, /* Encoding of z. 0 for BLOBs */ void (*xDel)(void*) /* Destructor function */){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); sqlite3VdbeMemRelease(pMem); if( !z ){ pMem->flags = MEM_Null; pMem->type = SQLITE_NULL; return SQLITE_OK; } pMem->z = (char *)z; if( xDel==SQLITE_STATIC ){ pMem->flags = MEM_Static; }else if( xDel==SQLITE_TRANSIENT ){ pMem->flags = MEM_Ephem; }else{ pMem->flags = MEM_Dyn; pMem->xDel = xDel; } pMem->enc = enc; pMem->type = enc==0 ? SQLITE_BLOB : SQLITE_TEXT; pMem->n = n; assert( enc==0 || enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); switch( enc ){ case 0: pMem->flags |= MEM_Blob; pMem->enc = SQLITE_UTF8; break; case SQLITE_UTF8: pMem->flags |= MEM_Str; if( n<0 ){ pMem->n = strlen(z); pMem->flags |= MEM_Term; } break;#ifndef SQLITE_OMIT_UTF16 case SQLITE_UTF16LE: case SQLITE_UTF16BE: pMem->flags |= MEM_Str; if( pMem->n<0 ){ pMem->n = sqlite3Utf16ByteLen(pMem->z,-1); pMem->flags |= MEM_Term; } if( sqlite3VdbeMemHandleBom(pMem) ){ return SQLITE_NOMEM; }#endif /* SQLITE_OMIT_UTF16 */ } if( pMem->flags&MEM_Ephem ){ return sqlite3VdbeMemMakeWriteable(pMem); } return SQLITE_OK;}/*** Compare the values contained by the two memory cells, returning** negative, zero or positive if pMem1 is less than, equal to, or greater** than pMem2. Sorting order is NULL's first, followed by numbers (integers** and reals) sorted numerically, followed by text ordered by the collating** sequence pColl and finally blob's ordered by memcmp().**** Two NULL values are considered equal by this function.*/int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ int rc; int f1, f2; int combined_flags; /* Interchange pMem1 and pMem2 if the collating sequence specifies ** DESC order. */ f1 = pMem1->flags; f2 = pMem2->flags; combined_flags = f1|f2; /* If one value is NULL, it is less than the other. If both values ** are NULL, return 0. */ if( combined_flags&MEM_Null ){ return (f2&MEM_Null) - (f1&MEM_Null); } /* If one value is a number and the other is not, the number is less. ** If both are numbers, compare as reals if one is a real, or as integers ** if both values are integers. */ if( combined_flags&(MEM_Int|MEM_Real) ){ if( !(f1&(MEM_Int|MEM_Real)) ){ return 1; } if( !(f2&(MEM_Int|MEM_Real)) ){ return -1; } if( (f1 & f2 & MEM_Int)==0 ){ double r1, r2; if( (f1&MEM_Real)==0 ){ r1 = pMem1->u.i; }else{ r1 = pMem1->r; } if( (f2&MEM_Real)==0 ){ r2 = pMem2->u.i; }else{ r2 = pMem2->r; } if( r1<r2 ) return -1; if( r1>r2 ) return 1; return 0; }else{ assert( f1&MEM_Int ); assert( f2&MEM_Int ); if( pMem1->u.i < pMem2->u.i ) return -1; if( pMem1->u.i > pMem2->u.i ) return 1; return 0; } } /* If one value is a string and the other is a blob, the string is less. ** If both are strings, compare using the collating functions. */ if( combined_flags&MEM_Str ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -