📄 vdbeaux.c
字号:
sqlite3VdbeDelete(p); return rc;}/*** Call the destructor for each auxdata entry in pVdbeFunc for which** the corresponding bit in mask is clear. Auxdata entries beyond 31** 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; if( p==0 ) return; Cleanup(p); if( p->pPrev ){ p->pPrev->pNext = p->pNext; }else{ assert( p->db->pVdbe==p ); p->db->pVdbe = p->pNext; } if( p->pNext ){ p->pNext->pPrev = p->pPrev; } if( p->aOp ){ for(i=0; i<p->nOp; i++){ Op *pOp = &p->aOp[i]; if( pOp->p3type==P3_DYNAMIC || pOp->p3type==P3_KEYINFO ){ sqliteFree(pOp->p3); } if( pOp->p3type==P3_VDBEFUNC ){ VdbeFunc *pVdbeFunc = (VdbeFunc *)pOp->p3; sqlite3VdbeDeleteAuxData(pVdbeFunc, 0); sqliteFree(pVdbeFunc); } if( pOp->p3type==P3_MEM ){ sqlite3ValueFree((sqlite3_value*)pOp->p3); } } sqliteFree(p->aOp); } releaseMemArray(p->aVar, p->nVar); sqliteFree(p->aLabel); sqliteFree(p->aStack); releaseMemArray(p->aColName, p->nResColumn*2); sqliteFree(p->aColName); p->magic = VDBE_MAGIC_DEAD; sqliteFree(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; extern int sqlite3_search_count; assert( p->isTable ); if( p->isTable ){ rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res); }else{ rc = sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget, sizeof(i64),&res); } if( rc ) return rc; *p->pIncrKey = 0; p->lastRowid = keyToInt(p->movetoTarget); p->rowidIsValid = res==0; if( res<0 ){ rc = sqlite3BtreeNext(p->pCursor, &res); if( rc ) return rc; } sqlite3_search_count++; p->deferredMoveto = 0; p->cacheValid = 0; } return SQLITE_OK;}/*** The following functions:**** sqlite3VdbeSerialType()** sqlite3VdbeSerialTypeLen()** sqlite3VdbeSerialRead()** sqlite3VdbeSerialLen()** sqlite3VdbeSerialWrite()**** 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-11 reserved for expansion** N>=12 and even (N-12)/2 BLOB** N>=13 and odd (N-13)/2 text***//*** Return the serial-type for the value stored in pMem.*/u32 sqlite3VdbeSerialType(Mem *pMem){ int flags = pMem->flags; 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)0x00001000)<<32)-1) i64 i = pMem->i; u64 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; } if( flags&MEM_Str ){ int n = pMem->n; assert( n>=0 ); return ((n*2) + 13); } if( flags&MEM_Blob ){ return (pMem->n*2 + 12); } return 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]; }}/*** 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.*/ int sqlite3VdbeSerialPut(unsigned char *buf, Mem *pMem){ u32 serial_type = sqlite3VdbeSerialType(pMem); int len; /* NULL */ if( serial_type==0 ){ return 0; } /* Integer and Real */ if( serial_type<=7 ){ u64 v; int i; if( serial_type==7 ){ v = *(u64*)&pMem->r; }else{ v = *(u64*)&pMem->i; } len = i = sqlite3VdbeSerialTypeLen(serial_type); while( i-- ){ buf[i] = (v&0xFF); v >>= 8; } return len; } /* String or blob */ assert( serial_type>=12 ); len = sqlite3VdbeSerialTypeLen(serial_type); memcpy(buf, pMem->z, len); return len;}/*** 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 8: /* Reserved for future use */ case 9: /* Reserved for future use */ 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->i = (signed char)buf[0]; pMem->flags = MEM_Int; return 1; } case 2: { /* 2-byte signed integer */ pMem->i = (((signed char)buf[0])<<8) | buf[1]; pMem->flags = MEM_Int; return 2; } case 3: { /* 3-byte signed integer */ pMem->i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2]; pMem->flags = MEM_Int; return 3; } case 4: { /* 4-byte signed integer */ pMem->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->i = *(i64*)&x; pMem->flags = MEM_Int; return 6; } case 6: /* 6-byte signed integer */ case 7: { /* IEEE floating point */ u64 x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3]; u32 y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7]; x = (x<<32) | y; if( serial_type==6 ){ pMem->i = *(i64*)&x; pMem->flags = MEM_Int; }else{ pMem->r = *(double*)&x; pMem->flags = MEM_Real; } return 8; } 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;}/*** This function compares the two table rows or index records specified by ** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero** or positive integer if {nKey1, pKey1} is less than, equal to or ** greater than {nKey2, pKey2}. Both Key1 and Key2 must be byte strings** composed by the OP_MakeRecord opcode of the VDBE.*/int sqlite3VdbeRecordCompare( void *userData, int nKey1, const void *pKey1, int nKey2, const void *pKey2){ KeyInfo *pKeyInfo = (KeyInfo*)userData; u32 d1, d2; /* Offset into aKey[] of next data element */ u32 idx1, idx2; /* Offset into aKey[] of next header element */ u32 szHdr1, szHdr2; /* Number of bytes in header */ int i = 0; int nField; int rc = 0; const unsigned char *aKey1 = (const unsigned char *)pKey1; const unsigned char *aKey2 = (const unsigned char *)pKey2; Mem mem1; Mem mem2; mem1.enc = pKeyInfo->enc; mem2.enc = pKeyInfo->enc; idx1 = sqlite3GetVarint32(pKey1, &szHdr1); d1 = szHdr1; idx2 = sqlite3GetVarint32(pKey2, &szHdr2); d2 = szHdr2; nField = pKeyInfo->nField; while( idx1<szHdr1 && idx2<szHdr2 ){ u32 serial_type1; u32 serial_type2; /* Read the serial types for the next element in each key. */ idx1 += sqlite3GetVarint32(&aKey1[idx1], &serial_type1); if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break; idx2 += sqlite3GetVarint32(&aKey2[idx2], &serial_type2); if( d2>=nKey2 && sqlite3VdbeSerialTypeLen(serial_type2)>0 ) break; /* Assert that there is enough space left in each key for the blob of ** data to go with the serial type just read. This assert may fail if ** the file is corrupted. Then read the value from each key into mem1 ** and mem2 respectively. */ d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1); d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2); rc = sqlite3MemCompare(&mem1, &mem2, i<nField ? pKeyInfo->aColl[i] : 0); if( mem1.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem1); if( mem2.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem2); if( rc!=0 ){ break; } i++; } /* One of the keys ran out of fields, but all the fields up to that point ** were equal. If the incrKey flag is true, then the second key is ** treated as larger. */ if( rc==0 ){ if( pKeyInfo->incrKey ){ rc = -1; }else if( d1<nKey1 ){ rc = 1; }else if( d2<nKey2 ){ rc = -1; } } if( pKeyInfo->aSortOrder && i<pKeyInfo->nField && pKeyInfo->aSortOrder[i] ){ rc = -rc; } return rc;}/*** The argument is an index entry composed using the OP_MakeRecord opcode.** The last entry in this record should be an integer (specifically** an integer rowid). This routine returns the number of bytes in** that integer.*/int sqlite3VdbeIdxRowidLen(int nKey, const u8 *aKey){ u32 szHdr; /* Size of the header */ u32 typeRowid; /* Serial type of the rowid */ sqlite3GetVarint32(aKey, &szHdr); sqlite3GetVarint32(&aKey[szHdr-1], &typeRowid); return sqlite3VdbeSerialTypeLen(typeRowid);} /*** pCur points at an index entry created using the OP_MakeRecord opcode.** Read the rowid (the last field in the record) and store it in *rowid.** Return SQLITE_OK if everything works, or an error code otherwise.*/int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){ i64 nCellKey; int rc; u32 szHdr; /* Size of the header */ u32 typeRowid; /* Serial type of the rowid */ u32 lenRowid; /* Size of the rowid */ Mem m, v; sqlite3BtreeKeySize(pCur, &nCellKey); if( nCellKey<=0 ){ return SQLITE_CORRUPT; } rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m); if( rc ){ return rc; } sqlite3GetVarint32(m.z, &szHdr); sqlite3GetVarint32(&m.z[szHdr-1], &typeRowid); lenRowid = sqlite3VdbeSerialTypeLen(typeRowid); sqlite3VdbeSerialGet(&m.z[m.n-lenRowid], typeRowid, &v); *rowid = v.i; sqlite3VdbeMemRelease(&m); return SQLITE_OK;}/*** Compare the key of the index entry that cursor pC is point to against** the key string in pKey (of length nKey). Write into *pRes a number** that is negative, zero, or positive if pC is less than, equal to,** or greater than pKey. Return SQLITE_OK on success.**** pKey is either created without a rowid or is truncated so that it** omits the rowid at the end. The rowid at the end of the index entry** is ignored as well.*/int sqlite3VdbeIdxKeyCompare( Cursor *pC, /* The cursor to compare against */ int nKey, const u8 *pKey, /* The key to compare */ int *res /* Write the comparison result here */){ i64 nCellKey; int rc; BtCursor *pCur = pC->pCursor; int lenRowid; Mem m; sqlite3BtreeKeySize(pCur, &nCellKey); if( nCellKey<=0 ){ *res = 0; return SQLITE_OK; } rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m); if( rc ){ return rc; } lenRowid = sqlite3VdbeIdxRowidLen(m.n, m.z); *res = sqlite3VdbeRecordCompare(pC->pKeyInfo, m.n-lenRowid, m.z, nKey, pKey); sqlite3VdbeMemRelease(&m); return SQLITE_OK;}/*** This routine sets the value to be returned by subsequent calls to** sqlite3_changes() on the database handle 'db'. */void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){ db->nChange = nChange; db->nTotalChange += nChange;}/*** Set a flag in the vdbe to update the change counter when it is finalised** or reset.*/void sqlite3VdbeCountChanges(Vdbe *v){ v->changeCntOn = 1;}/*** Mark every prepared statement associated with a database connection** as expired.**** An expired statement means that recompilation of the statement is** recommend. Statements expire when things happen that make their** programs obsolete. Removing user-defined functions or collating** sequences, or changing an authorization function are the types of** things that make prepared statements obsolete.*/void sqlite3ExpirePreparedStatements(sqlite3 *db){ Vdbe *p; for(p = db->pVdbe; p; p=p->pNext){ p->expired = 1; }}/*** Return the database associated with the Vdbe.*/sqlite3 *sqlite3VdbeDb(Vdbe *v){ return v->db;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -