Refactor the sqlite3VdbeRecordUnpack() interface to better accommodate the vdbesort.c module.
FossilOrigin-Name: f115b2303509c678dbe83b2fa3d9c40d82882813
This commit is contained in:
parent
19c88c1a99
commit
03e9cfc223
22
manifest
22
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\sa\scompiler\swarning\sabout\san\sunused\sparameter\sin\sthe\smerge-sort\scode.
|
||||
D 2011-09-04T01:27:00.510
|
||||
C Refactor\sthe\ssqlite3VdbeRecordUnpack()\sinterface\sto\sbetter\saccommodate\sthe\svdbesort.c\smodule.
|
||||
D 2011-09-05T14:20:27.320
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in d314143fa6be24828021d3f583ad37d9afdce505
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -124,7 +124,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
||||
F src/backup.c 28a4fe55327ff708bfaf9d4326d02686f7a553c3
|
||||
F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
|
||||
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||
F src/btree.c 4d46fe30b8bc920f68b7d58a5f45316fa5d023ec
|
||||
F src/btree.c 958f26c8f5ff001791ba1ba3825e69d1a383c2fd
|
||||
F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce
|
||||
F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3
|
||||
F src/build.c 851e81f26a75abbb98bd99a7c5f10e8670d867bb
|
||||
@ -238,14 +238,14 @@ F src/update.c 74a6cfb34e9732c1e2a86278b229913b4b51eeec
|
||||
F src/utf.c c53eb7404b3eb5c1cbb5655c6a7a0e0ce6bd50f0
|
||||
F src/util.c 06302ffd2b80408d4f6c7af71f7090e0cf8d8ff7
|
||||
F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e
|
||||
F src/vdbe.c d4c8224cc931c6082557501d7f822fb12f273922
|
||||
F src/vdbe.h c1eeedacab6bcf1e7c2cf8203ba9763a616f9a86
|
||||
F src/vdbe.c 7008edbf8f608d82c035dcb1c56367ad85e68aaa
|
||||
F src/vdbe.h a10b360bf69474babc8aba8fcc64b824c5e97d38
|
||||
F src/vdbeInt.h 693d6ac6810298fc6b4c503cfbe3f99a240f40af
|
||||
F src/vdbeapi.c 11dc47987abacb76ad016dcf5abc0dc422482a98
|
||||
F src/vdbeaux.c e58acbc5ea3823922a0cd8fa21f94f39af51ee88
|
||||
F src/vdbeaux.c 8546b9481d8c642f2403ae8ebf20823b54e00606
|
||||
F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3
|
||||
F src/vdbemem.c 5e6effb96dd53d233361cbfaa3f0a43b9af689e9
|
||||
F src/vdbesort.c 14d127565bab1032a20558e6c9ae5f2ec0499111
|
||||
F src/vdbesort.c 4f3265707c3277011fbb0c09d3d8e6461152f639
|
||||
F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114
|
||||
F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582
|
||||
F src/wal.c 3154756177d6219e233d84291d5b05f4e06ff5e9
|
||||
@ -961,7 +961,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5
|
||||
F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2
|
||||
P b5179baf87aa00ed5cecbdcaa65bee10e112a9e9
|
||||
R 19f8e6b3aaa4f6faa3ce68485711b8fa
|
||||
U drh
|
||||
Z c68d8b01f68570c73b0670afe2bb6a90
|
||||
P 6b657ae75035eb10b0ad640998d3c9eadfdffa6e
|
||||
R 17c6c62caa602109512a646943ac3f7f
|
||||
U dan
|
||||
Z 1812248ebcb21a3973c4b6e0222ea90b
|
||||
|
@ -1 +1 @@
|
||||
6b657ae75035eb10b0ad640998d3c9eadfdffa6e
|
||||
f115b2303509c678dbe83b2fa3d9c40d82882813
|
@ -656,18 +656,21 @@ static int btreeMoveto(
|
||||
int rc; /* Status code */
|
||||
UnpackedRecord *pIdxKey; /* Unpacked index key */
|
||||
char aSpace[150]; /* Temp space for pIdxKey - to avoid a malloc */
|
||||
char *pFree = 0;
|
||||
|
||||
if( pKey ){
|
||||
assert( nKey==(i64)(int)nKey );
|
||||
pIdxKey = sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey,
|
||||
aSpace, sizeof(aSpace));
|
||||
pIdxKey = sqlite3VdbeAllocUnpackedRecord(
|
||||
pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree
|
||||
);
|
||||
if( pIdxKey==0 ) return SQLITE_NOMEM;
|
||||
sqlite3VdbeRecordUnpack(pCur->pKeyInfo, nKey, pKey, pIdxKey);
|
||||
}else{
|
||||
pIdxKey = 0;
|
||||
}
|
||||
rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes);
|
||||
if( pKey ){
|
||||
sqlite3VdbeDeleteUnpackedRecord(pIdxKey);
|
||||
sqlite3DbFree(pCur->pKeyInfo->db, pFree);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
13
src/vdbe.c
13
src/vdbe.c
@ -3531,6 +3531,7 @@ case OP_Found: { /* jump, in3 */
|
||||
int alreadyExists;
|
||||
VdbeCursor *pC;
|
||||
int res;
|
||||
char *pFree;
|
||||
UnpackedRecord *pIdxKey;
|
||||
UnpackedRecord r;
|
||||
char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
|
||||
@ -3558,18 +3559,18 @@ case OP_Found: { /* jump, in3 */
|
||||
r.flags = UNPACKED_PREFIX_MATCH;
|
||||
pIdxKey = &r;
|
||||
}else{
|
||||
pIdxKey = sqlite3VdbeAllocUnpackedRecord(
|
||||
pC->pKeyInfo, aTempRec, sizeof(aTempRec), &pFree
|
||||
);
|
||||
if( pIdxKey==0 ) goto no_mem;
|
||||
assert( pIn3->flags & MEM_Blob );
|
||||
assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */
|
||||
pIdxKey = sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z,
|
||||
aTempRec, sizeof(aTempRec));
|
||||
if( pIdxKey==0 ){
|
||||
goto no_mem;
|
||||
}
|
||||
sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
|
||||
pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
|
||||
}
|
||||
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res);
|
||||
if( pOp->p4.i==0 ){
|
||||
sqlite3VdbeDeleteUnpackedRecord(pIdxKey);
|
||||
sqlite3DbFree(db, pFree);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
break;
|
||||
|
@ -212,9 +212,9 @@ void sqlite3VdbeSetVarmask(Vdbe*, int);
|
||||
char *sqlite3VdbeExpandSql(Vdbe*, const char*);
|
||||
#endif
|
||||
|
||||
UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,char*,int);
|
||||
void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*);
|
||||
void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
|
||||
int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
|
||||
UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
|
||||
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
|
||||
|
106
src/vdbeaux.c
106
src/vdbeaux.c
@ -2830,54 +2830,69 @@ u32 sqlite3VdbeSerialGet(
|
||||
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.
|
||||
** This routine is used to allocate sufficient space for an UnpackedRecord
|
||||
** structure large enough to be used with sqlite3VdbeRecordUnpack() if
|
||||
** the first argument is a pointer to KeyInfo structure pKeyInfo.
|
||||
**
|
||||
** 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 space is either allocated using sqlite3DbMallocRaw() or from within
|
||||
** the unaligned buffer passed via the second and third arguments (presumably
|
||||
** stack space). If the former, then *ppFree is set to a pointer that should
|
||||
** be eventually freed by the caller using sqlite3DbFree(). Or, if the
|
||||
** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL
|
||||
** before returning.
|
||||
**
|
||||
** 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 */
|
||||
char *pSpace, /* Unaligned space available to hold the object */
|
||||
int szSpace /* Size of pSpace[] in bytes */
|
||||
** If an OOM error occurs, NULL is returned.
|
||||
*/
|
||||
UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
|
||||
KeyInfo *pKeyInfo, /* Description of the record */
|
||||
char *pSpace, /* Unaligned space available */
|
||||
int szSpace, /* Size of pSpace[] in bytes */
|
||||
char **ppFree /* OUT: Caller should free this pointer */
|
||||
){
|
||||
const unsigned char *aKey = (const unsigned char *)pKey;
|
||||
UnpackedRecord *p; /* The unpacked record that we will return */
|
||||
int nByte; /* Memory space needed to hold p, in bytes */
|
||||
int d;
|
||||
u32 idx;
|
||||
u16 u; /* Unsigned loop counter */
|
||||
u32 szHdr;
|
||||
Mem *pMem;
|
||||
int nOff; /* Increase pSpace by this much to 8-byte align it */
|
||||
|
||||
/*
|
||||
** We want to shift the pointer pSpace up such that it is 8-byte aligned.
|
||||
UnpackedRecord *p; /* Unpacked record to return */
|
||||
int nOff; /* Increment pSpace by nOff to align it */
|
||||
int nByte; /* Number of bytes required for *p */
|
||||
|
||||
/* We want to shift the pointer pSpace up such that it is 8-byte aligned.
|
||||
** Thus, we need to calculate a value, nOff, between 0 and 7, to shift
|
||||
** it by. If pSpace is already 8-byte aligned, nOff should be zero.
|
||||
*/
|
||||
nOff = (8 - (SQLITE_PTR_TO_INT(pSpace) & 7)) & 7;
|
||||
pSpace += nOff;
|
||||
szSpace -= nOff;
|
||||
|
||||
nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1);
|
||||
if( nByte>szSpace ){
|
||||
p = sqlite3DbMallocRaw(pKeyInfo->db, nByte);
|
||||
if( p==0 ) return 0;
|
||||
p->flags = UNPACKED_NEED_FREE | UNPACKED_NEED_DESTROY;
|
||||
p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
|
||||
*ppFree = (char *)p;
|
||||
}else{
|
||||
p = (UnpackedRecord*)pSpace;
|
||||
p->flags = UNPACKED_NEED_DESTROY;
|
||||
*ppFree = 0;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** Given the nKey-byte encoding of a record in pKey[], populate the
|
||||
** UnpackedRecord structure indicated by the fourth argument with the
|
||||
** contents of the decoded record.
|
||||
*/
|
||||
void sqlite3VdbeRecordUnpack(
|
||||
KeyInfo *pKeyInfo, /* Information about the record format */
|
||||
int nKey, /* Size of the binary record */
|
||||
const void *pKey, /* The binary record */
|
||||
UnpackedRecord *p /* Populate this structure before returning. */
|
||||
){
|
||||
const unsigned char *aKey = (const unsigned char *)pKey;
|
||||
int d;
|
||||
u32 idx; /* Offset in aKey[] to read from */
|
||||
u16 u; /* Unsigned loop counter */
|
||||
u32 szHdr;
|
||||
Mem *pMem;
|
||||
|
||||
p->flags = 0;
|
||||
p->pKeyInfo = pKeyInfo;
|
||||
p->nField = pKeyInfo->nField + 1;
|
||||
p->aMem = pMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
|
||||
@ -2899,31 +2914,6 @@ UnpackedRecord *sqlite3VdbeRecordUnpack(
|
||||
}
|
||||
assert( u<=pKeyInfo->nField + 1 );
|
||||
p->nField = u;
|
||||
return (void*)p;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine destroys a UnpackedRecord object.
|
||||
*/
|
||||
void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){
|
||||
#ifdef SQLITE_DEBUG
|
||||
int i;
|
||||
Mem *pMem;
|
||||
|
||||
assert( p!=0 );
|
||||
assert( p->flags & UNPACKED_NEED_DESTROY );
|
||||
for(i=0, pMem=p->aMem; i<p->nField; i++, pMem++){
|
||||
/* The unpacked record is always constructed by the
|
||||
** sqlite3VdbeUnpackRecord() function above, which makes all
|
||||
** strings and blobs static. And none of the elements are
|
||||
** ever transformed, so there is never anything to delete.
|
||||
*/
|
||||
if( NEVER(pMem->zMalloc) ) sqlite3VdbeMemRelease(pMem);
|
||||
}
|
||||
#endif
|
||||
if( p->flags & UNPACKED_NEED_FREE ){
|
||||
sqlite3DbFree(p->pKeyInfo->db, p);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -104,8 +104,7 @@ struct VdbeSorter {
|
||||
SorterRecord *pRecord; /* Head of in-memory record list */
|
||||
int mnPmaSize; /* Minimum PMA size, in bytes */
|
||||
int mxPmaSize; /* Maximum PMA size, in bytes. 0==no limit */
|
||||
char *aSpace; /* Space for UnpackRecord() */
|
||||
int nSpace; /* Size of aSpace in bytes */
|
||||
UnpackedRecord *pUnpacked; /* Used to unpack keys */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -308,27 +307,19 @@ static int vdbeSorterCompare(
|
||||
){
|
||||
KeyInfo *pKeyInfo = pCsr->pKeyInfo;
|
||||
VdbeSorter *pSorter = pCsr->pSorter;
|
||||
char *aSpace = pSorter->aSpace;
|
||||
int nSpace = pSorter->nSpace;
|
||||
UnpackedRecord *r2;
|
||||
UnpackedRecord *r2 = pSorter->pUnpacked;
|
||||
int i;
|
||||
|
||||
if( aSpace==0 ){
|
||||
nSpace = ROUND8(sizeof(UnpackedRecord))+(pKeyInfo->nField+1)*sizeof(Mem);
|
||||
aSpace = (char *)sqlite3Malloc(nSpace);
|
||||
if( aSpace==0 ) return SQLITE_NOMEM;
|
||||
pSorter->aSpace = aSpace;
|
||||
pSorter->nSpace = nSpace;
|
||||
if( r2==0 ){
|
||||
char *pFree;
|
||||
r2 = sqlite3VdbeAllocUnpackedRecord(pKeyInfo, 0, 0, &pFree);
|
||||
if( r2==0 ) return SQLITE_NOMEM;
|
||||
assert( pFree==(char *)r2 );
|
||||
pSorter->pUnpacked = r2;
|
||||
}
|
||||
|
||||
if( pKey2 ){
|
||||
/* This call cannot fail. As the memory is already allocated. */
|
||||
r2 = sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, aSpace, nSpace);
|
||||
assert( r2 && (r2->flags & UNPACKED_NEED_FREE)==0 );
|
||||
assert( r2==(UnpackedRecord*)aSpace );
|
||||
}else{
|
||||
r2 = (UnpackedRecord *)aSpace;
|
||||
assert( !bOmitRowid );
|
||||
sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2);
|
||||
}
|
||||
|
||||
if( bOmitRowid ){
|
||||
@ -380,11 +371,11 @@ static int vdbeSorterDoCompare(VdbeCursor *pCsr, int iOut){
|
||||
}else{
|
||||
int res;
|
||||
int rc;
|
||||
assert( pCsr->pSorter->aSpace!=0 ); /* allocated in vdbeSorterMerge() */
|
||||
assert( pCsr->pSorter->pUnpacked!=0 ); /* allocated in vdbeSorterMerge() */
|
||||
rc = vdbeSorterCompare(
|
||||
pCsr, 0, p1->aKey, p1->nKey, p2->aKey, p2->nKey, &res
|
||||
);
|
||||
/* The vdbeSorterCompare() call cannot fail since pCsr->pSorter->aSpace
|
||||
/* The vdbeSorterCompare() call cannot fail since pCsr->pSorter->pUnpacked
|
||||
** has already been allocated. */
|
||||
assert( rc==SQLITE_OK );
|
||||
|
||||
@ -453,7 +444,7 @@ void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){
|
||||
sqlite3OsCloseFree(pSorter->pTemp1);
|
||||
}
|
||||
vdbeSorterRecordFree(db, pSorter->pRecord);
|
||||
sqlite3_free(pSorter->aSpace);
|
||||
sqlite3DbFree(db, pSorter->pUnpacked);
|
||||
sqlite3DbFree(db, pSorter);
|
||||
pCsr->pSorter = 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user