📄 vdbeaux.c
字号:
** are always destroyed. To destroy all auxdata entries, call this** routine with mask==0.*/void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){ int i; for(i=0; i<pVdbeFunc->nAux; i++){ struct AuxData *pAux = &pVdbeFunc->apAux[i]; if( (i>31 || !(mask&(1<<i))) && pAux->pAux ){ if( pAux->xDelete ){ pAux->xDelete(pAux->pAux); } pAux->pAux = 0; } }}/*** Delete an entire VDBE.*/void sqlite3VdbeDelete(Vdbe *p){ int i; sqlite3 *db; if( p==0 ) return; db = p->db; if( p->pPrev ){ p->pPrev->pNext = p->pNext; }else{ assert( db->pVdbe==p ); db->pVdbe = p->pNext; } if( p->pNext ){ p->pNext->pPrev = p->pPrev; } if( p->aOp ){ Op *pOp = p->aOp; for(i=0; i<p->nOp; i++, pOp++){ freeP4(db, pOp->p4type, pOp->p4.p);#ifdef SQLITE_DEBUG sqlite3DbFree(db, pOp->zComment);#endif } sqlite3DbFree(db, p->aOp); } releaseMemArray(p->aVar, p->nVar); sqlite3DbFree(db, p->aLabel); if( p->aMem ){ sqlite3DbFree(db, &p->aMem[1]); } releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); sqlite3DbFree(db, p->aColName); sqlite3DbFree(db, p->zSql); p->magic = VDBE_MAGIC_DEAD; sqlite3DbFree(db, p);}/*** If a MoveTo operation is pending on the given cursor, then do that** MoveTo now. Return an error code. If no MoveTo is pending, this** routine does nothing and returns SQLITE_OK.*/int sqlite3VdbeCursorMoveto(Cursor *p){ if( p->deferredMoveto ){ int res, rc;#ifdef SQLITE_TEST extern int sqlite3_search_count;#endif assert( p->isTable ); rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); if( rc ) return rc; p->lastRowid = keyToInt(p->movetoTarget); p->rowidIsValid = res==0; if( res<0 ){ rc = sqlite3BtreeNext(p->pCursor, &res); if( rc ) return rc; }#ifdef SQLITE_TEST sqlite3_search_count++;#endif p->deferredMoveto = 0; p->cacheStatus = CACHE_STALE; }else if( p->pCursor ){ int hasMoved; int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved); if( rc ) return rc; if( hasMoved ){ p->cacheStatus = CACHE_STALE; p->nullRow = 1; } } return SQLITE_OK;}/*** The following functions:**** sqlite3VdbeSerialType()** sqlite3VdbeSerialTypeLen()** sqlite3VdbeSerialLen()** sqlite3VdbeSerialPut()** sqlite3VdbeSerialGet()**** encapsulate the code that serializes values for storage in SQLite** data and index records. Each serialized value consists of a** 'serial-type' and a blob of data. The serial type is an 8-byte unsigned** integer, stored as a varint.**** In an SQLite index record, the serial type is stored directly before** the blob of data that it corresponds to. In a table record, all serial** types are stored at the start of the record, and the blobs of data at** the end. Hence these functions allow the caller to handle the** serial-type and data blob seperately.**** The following table describes the various storage classes for data:**** serial type bytes of data type** -------------- --------------- ---------------** 0 0 NULL** 1 1 signed integer** 2 2 signed integer** 3 3 signed integer** 4 4 signed integer** 5 6 signed integer** 6 8 signed integer** 7 8 IEEE float** 8 0 Integer constant 0** 9 0 Integer constant 1** 10,11 reserved for expansion** N>=12 and even (N-12)/2 BLOB** N>=13 and odd (N-13)/2 text**** The 8 and 9 types were added in 3.3.0, file format 4. Prior versions** of SQLite will not understand those serial types.*//*** Return the serial-type for the value stored in pMem.*/u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){ int flags = pMem->flags; int n; if( flags&MEM_Null ){ return 0; } if( flags&MEM_Int ){ /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */# define MAX_6BYTE ((((i64)0x00008000)<<32)-1) i64 i = pMem->u.i; u64 u; if( file_format>=4 && (i&1)==i ){ return 8+i; } u = i<0 ? -i : i; if( u<=127 ) return 1; if( u<=32767 ) return 2; if( u<=8388607 ) return 3; if( u<=2147483647 ) return 4; if( u<=MAX_6BYTE ) return 5; return 6; } if( flags&MEM_Real ){ return 7; } assert( flags&(MEM_Str|MEM_Blob) ); n = pMem->n; if( flags & MEM_Zero ){ n += pMem->u.i; } assert( n>=0 ); return ((n*2) + 12 + ((flags&MEM_Str)!=0));}/*** Return the length of the data corresponding to the supplied serial-type.*/int sqlite3VdbeSerialTypeLen(u32 serial_type){ if( serial_type>=12 ){ return (serial_type-12)/2; }else{ static const u8 aSize[] = { 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0 }; return aSize[serial_type]; }}/*** If we are on an architecture with mixed-endian floating ** points (ex: ARM7) then swap the lower 4 bytes with the ** upper 4 bytes. Return the result.**** For most architectures, this is a no-op.**** (later): It is reported to me that the mixed-endian problem** on ARM7 is an issue with GCC, not with the ARM7 chip. It seems** that early versions of GCC stored the two words of a 64-bit** float in the wrong order. And that error has been propagated** ever since. The blame is not necessarily with GCC, though.** GCC might have just copying the problem from a prior compiler.** I am also told that newer versions of GCC that follow a different** ABI get the byte order right.**** Developers using SQLite on an ARM7 should compile and run their** application using -DSQLITE_DEBUG=1 at least once. With DEBUG** enabled, some asserts below will ensure that the byte order of** floating point values is correct.**** (2007-08-30) Frank van Vugt has studied this problem closely** and has send his findings to the SQLite developers. Frank** writes that some Linux kernels offer floating point hardware** emulation that uses only 32-bit mantissas instead of a full ** 48-bits as required by the IEEE standard. (This is the** CONFIG_FPE_FASTFPE option.) On such systems, floating point** byte swapping becomes very complicated. To avoid problems,** the necessary byte swapping is carried out using a 64-bit integer** rather than a 64-bit float. Frank assures us that the code here** works for him. We, the developers, have no way to independently** verify this, but Frank seems to know what he is talking about** so we trust him.*/#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOATstatic u64 floatSwap(u64 in){ union { u64 r; u32 i[2]; } u; u32 t; u.r = in; t = u.i[0]; u.i[0] = u.i[1]; u.i[1] = t; return u.r;}# define swapMixedEndianFloat(X) X = floatSwap(X)#else# define swapMixedEndianFloat(X)#endif/*** Write the serialized data blob for the value stored in pMem into ** buf. It is assumed that the caller has allocated sufficient space.** Return the number of bytes written.**** nBuf is the amount of space left in buf[]. nBuf must always be** large enough to hold the entire field. Except, if the field is** a blob with a zero-filled tail, then buf[] might be just the right** size to hold everything except for the zero-filled tail. If buf[]** is only big enough to hold the non-zero prefix, then only write that** prefix into buf[]. But if buf[] is large enough to hold both the** prefix and the tail then write the prefix and set the tail to all** zeros.**** Return the number of bytes actually written into buf[]. The number** of bytes in the zero-filled tail is included in the return value only** if those bytes were zeroed in buf[].*/ int sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){ u32 serial_type = sqlite3VdbeSerialType(pMem, file_format); int len; /* Integer and Real */ if( serial_type<=7 && serial_type>0 ){ u64 v; int i; if( serial_type==7 ){ assert( sizeof(v)==sizeof(pMem->r) ); memcpy(&v, &pMem->r, sizeof(v)); swapMixedEndianFloat(v); }else{ v = pMem->u.i; } len = i = sqlite3VdbeSerialTypeLen(serial_type); assert( len<=nBuf ); while( i-- ){ buf[i] = (v&0xFF); v >>= 8; } return len; } /* String or blob */ if( serial_type>=12 ){ assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.i:0) == sqlite3VdbeSerialTypeLen(serial_type) ); assert( pMem->n<=nBuf ); len = pMem->n; memcpy(buf, pMem->z, len); if( pMem->flags & MEM_Zero ){ len += pMem->u.i; if( len>nBuf ){ len = nBuf; } memset(&buf[pMem->n], 0, len-pMem->n); } return len; } /* NULL or constants 0 or 1 */ return 0;}/*** Deserialize the data blob pointed to by buf as serial type serial_type** and store the result in pMem. Return the number of bytes read.*/ int sqlite3VdbeSerialGet( const unsigned char *buf, /* Buffer to deserialize from */ u32 serial_type, /* Serial type to deserialize */ Mem *pMem /* Memory cell to write value into */){ switch( serial_type ){ case 10: /* Reserved for future use */ case 11: /* Reserved for future use */ case 0: { /* NULL */ pMem->flags = MEM_Null; break; } case 1: { /* 1-byte signed integer */ pMem->u.i = (signed char)buf[0]; pMem->flags = MEM_Int; return 1; } case 2: { /* 2-byte signed integer */ pMem->u.i = (((signed char)buf[0])<<8) | buf[1]; pMem->flags = MEM_Int; return 2; } case 3: { /* 3-byte signed integer */ pMem->u.i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2]; pMem->flags = MEM_Int; return 3; } case 4: { /* 4-byte signed integer */ pMem->u.i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3]; pMem->flags = MEM_Int; return 4; } case 5: { /* 6-byte signed integer */ u64 x = (((signed char)buf[0])<<8) | buf[1]; u32 y = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5]; x = (x<<32) | y; pMem->u.i = *(i64*)&x; pMem->flags = MEM_Int; return 6; } case 6: /* 8-byte signed integer */ case 7: { /* IEEE floating point */ u64 x; u32 y;#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT) /* Verify that integers and floating point values use the same ** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is ** defined that 64-bit floating point values really are mixed ** endian. */ static const u64 t1 = ((u64)0x3ff00000)<<32; static const double r1 = 1.0; u64 t2 = t1; swapMixedEndianFloat(t2); assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );#endif x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3]; y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7]; x = (x<<32) | y; if( serial_type==6 ){ pMem->u.i = *(i64*)&x; pMem->flags = MEM_Int; }else{ assert( sizeof(x)==8 && sizeof(pMem->r)==8 ); swapMixedEndianFloat(x); memcpy(&pMem->r, &x, sizeof(x)); pMem->flags = sqlite3IsNaN(pMem->r) ? MEM_Null : MEM_Real; } return 8; } case 8: /* Integer 0 */ case 9: { /* Integer 1 */ pMem->u.i = serial_type-8; pMem->flags = MEM_Int; return 0; } default: { int len = (serial_type-12)/2; pMem->z = (char *)buf; pMem->n = len; pMem->xDel = 0; if( serial_type&0x01 ){ pMem->flags = MEM_Str | MEM_Ephem; }else{ pMem->flags = MEM_Blob | MEM_Ephem; } return len; } } return 0;}/*** Given the nKey-byte encoding of a record in pKey[], parse the** record into a UnpackedRecord structure. Return a pointer to** that structure.**** The calling function might provide szSpace bytes of memory** space at pSpace. This space can be used to hold the returned** VDbeParsedRecord structure if it is large enough. If it is** not big enough, space is obtained from sqlite3_malloc().**** The returned structure should be closed by a call to** sqlite3VdbeDeleteUnpackedRecord().*/ UnpackedRecord *sqlite3VdbeRecordUnpack( KeyInfo *pKeyInfo, /* Information about the record format */ int nKey, /* Size of the binary record */ const void *pKey, /* The binary record */ UnpackedRecord *pSpace,/* Space available to hold resulting object */ int szSpace /* Size of pSpace[] in bytes */){ const unsigned char *aKey = (const unsigned char *)pKey; UnpackedRecord *p; int nByte; int idx, d; u16 u; /* Unsigned loop counter */ u32 szHdr; Mem *pMem; assert( sizeof(Mem)>sizeof(*p) ); nByte = sizeof(Mem)*(pKeyInfo->nField+2); if( nByte>szSpace ){ p = sqlite3DbMallocRaw(pKeyInfo->db, nByte); if( p==0 ) return 0; p->flags = UNPACKED_NEED_FREE | UNPACKED_NEED_DESTROY; }else{ p = pSpace; p->flags = UNPACKED_NEED_DESTROY; } p->pKeyInfo = pKeyInfo; p->nField = pKeyInfo->nField + 1; p->aMem = pMem = &((Mem*)p)[1]; idx = getVarint32(aKey, szHdr); d =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -