Also free up the MEM_RowSet bit in the Mem.flags field and have RowSet objects
be destroyed using Mem.xDel. This change results in faster code. FossilOrigin-Name: f48e9feb3fca514e4e586932e6d19a5e34a384204effeba553006dcddf5f13d2
This commit is contained in:
parent
72f56ef95d
commit
9d67afc421
22
manifest
22
manifest
@ -1,5 +1,5 @@
|
|||||||
C Free\sup\sthe\sMEM_Frame\sbit\sin\sMem.flags\sobject.\s\sStore\sVdbeFrame\sobjects\nas\sMEM_Blob\swith\sa\sspecial\sMem.xDel\spointer\sinstead.
|
C Also\sfree\sup\sthe\sMEM_RowSet\sbit\sin\sthe\sMem.flags\sfield\sand\shave\sRowSet\sobjects\nbe\sdestroyed\susing\sMem.xDel.\s\sThis\schange\sresults\sin\sfaster\scode.
|
||||||
D 2018-08-29T18:47:22.883
|
D 2018-08-29T20:24:03.572
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F Makefile.in d06f463c5b623a61ac27f5cb8214fca9e53a6704d34d6b8f2124e2b1b293c88f
|
F Makefile.in d06f463c5b623a61ac27f5cb8214fca9e53a6704d34d6b8f2124e2b1b293c88f
|
||||||
@ -499,13 +499,13 @@ F src/prepare.c e966ecc97c3671ff0e96227c8c877b83f2d33ea371ee190bbf1698b36b5605c0
|
|||||||
F src/printf.c 7f6f3cba8e0c49c19e30a1ff4e9aeda6e06814dcbad4b664a69e1b6cb6e7e365
|
F src/printf.c 7f6f3cba8e0c49c19e30a1ff4e9aeda6e06814dcbad4b664a69e1b6cb6e7e365
|
||||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||||
F src/resolve.c 797088662ed61102485e3070ba3b3f7828bd5ef6a588223ba6865d77d52f6cea
|
F src/resolve.c 797088662ed61102485e3070ba3b3f7828bd5ef6a588223ba6865d77d52f6cea
|
||||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
|
||||||
F src/select.c ae7396a314cc1bb1d767947cd57094e3a9ffcbb155ebc1b1c391e028c44a9a04
|
F src/select.c ae7396a314cc1bb1d767947cd57094e3a9ffcbb155ebc1b1c391e028c44a9a04
|
||||||
F src/shell.c.in 6e0aad854be738a5d0368940459399be211e9ac43aebe92bb9ed46cfe38d0e1f
|
F src/shell.c.in 6e0aad854be738a5d0368940459399be211e9ac43aebe92bb9ed46cfe38d0e1f
|
||||||
F src/sqlite.h.in 5a2d431493020c2c9f2f37c9119d6439444e3c44a714566a5192b6911ac917e6
|
F src/sqlite.h.in 5a2d431493020c2c9f2f37c9119d6439444e3c44a714566a5192b6911ac917e6
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7
|
F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7
|
||||||
F src/sqliteInt.h 2a670143a4f6b7d85958bac125e4d9d8ad14f016a3582e9d7c6907d9d50b75a0
|
F src/sqliteInt.h 26e48f0c823844fcce67bd2a11ad1ad3468aaed32fd8864bc69c4147cb608728
|
||||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||||
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
|
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
|
||||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||||
@ -571,13 +571,13 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
|
|||||||
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
|
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
|
||||||
F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
|
F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
|
||||||
F src/vacuum.c 36e7d21a20c0bf6ef4ef7c399d192b5239410b7c4d3c1070fba4e30810d0b855
|
F src/vacuum.c 36e7d21a20c0bf6ef4ef7c399d192b5239410b7c4d3c1070fba4e30810d0b855
|
||||||
F src/vdbe.c a44a1cd246f808d36ee0ce7dc031d9624a50242db96ac57f65ad93aea65ceaac
|
F src/vdbe.c 74671dff9ba856c5464557a8dbf2ba940fc4fa67efbceb32e262eedac31d86ca
|
||||||
F src/vdbe.h 5081dcc497777efe5e9ebe7330d283a044a005e4bdda2e2e984f03bf89a0d907
|
F src/vdbe.h 5081dcc497777efe5e9ebe7330d283a044a005e4bdda2e2e984f03bf89a0d907
|
||||||
F src/vdbeInt.h a660268d9e60dcd60abe8768c1582dd35f3d174ad12f742aee8c805af72dac03
|
F src/vdbeInt.h f1f35f70460698d8f5a2bdef1001114babf318e2983a067804e2ae077d8e9827
|
||||||
F src/vdbeapi.c 2ba821c5929a2769e4b217dd85843479c718b8989d414723ec8af0616a83d611
|
F src/vdbeapi.c 2ba821c5929a2769e4b217dd85843479c718b8989d414723ec8af0616a83d611
|
||||||
F src/vdbeaux.c 20da0273e9bdb3f49dafa71123d7bdd63b2656134ecd73123562c028847d0e07
|
F src/vdbeaux.c 1ee77344fe9fd6ac11fae6f0150f81e0eadf349a9957340089cf82284e6b379a
|
||||||
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
|
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
|
||||||
F src/vdbemem.c 9a9aa4262f2c5620a552ad83902379d9b1dbb792eb4c1e8758ffffa7ab8a2e64
|
F src/vdbemem.c 81329ab760e4ec0162119d9cd10193e0303c45c5935bb20c7ae9139d44dd6641
|
||||||
F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f
|
F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f
|
||||||
F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
|
F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
|
||||||
F src/vtab.c 678992ac8ec677a3f9b08126aaf891441083805e3b42574e3654d44538381c14
|
F src/vtab.c 678992ac8ec677a3f9b08126aaf891441083805e3b42574e3654d44538381c14
|
||||||
@ -1758,7 +1758,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 2d4debccbc027405a33aeb10f9d65f6fe4bfb5eb1be5a4d8b82158caba04643f
|
P 62db5fd47660bbc4fcf2c6d4a6c5a3077f12c6442a128d22b66b789a0409ef32
|
||||||
R bd76e3ebc281873295239e9b6605a092
|
R b874f6bc6fe7e6d492c17f3293f43632
|
||||||
U drh
|
U drh
|
||||||
Z 6a1519aefdfc6d3a0da507442f0a767b
|
Z e2bd09cc55c8cf3a3298f3d931f8e0b9
|
||||||
|
@ -1 +1 @@
|
|||||||
62db5fd47660bbc4fcf2c6d4a6c5a3077f12c6442a128d22b66b789a0409ef32
|
f48e9feb3fca514e4e586932e6d19a5e34a384204effeba553006dcddf5f13d2
|
52
src/rowset.c
52
src/rowset.c
@ -124,30 +124,23 @@ struct RowSet {
|
|||||||
#define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */
|
#define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Turn bulk memory into a RowSet object. N bytes of memory
|
** Allocate a RowSet object. Return NULL if a memory allocation
|
||||||
** are available at pSpace. The db pointer is used as a memory context
|
** error occurs.
|
||||||
** for any subsequent allocations that need to occur.
|
|
||||||
** Return a pointer to the new RowSet object.
|
|
||||||
**
|
|
||||||
** It must be the case that N is sufficient to make a Rowset. If not
|
|
||||||
** an assertion fault occurs.
|
|
||||||
**
|
|
||||||
** If N is larger than the minimum, use the surplus as an initial
|
|
||||||
** allocation of entries available to be filled.
|
|
||||||
*/
|
*/
|
||||||
RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
|
RowSet *sqlite3RowSetInit(sqlite3 *db){
|
||||||
RowSet *p;
|
RowSet *p = sqlite3DbMallocRawNN(db, sizeof(*p));
|
||||||
assert( N >= ROUND8(sizeof(*p)) );
|
if( p ){
|
||||||
p = pSpace;
|
int N = sqlite3DbMallocSize(db, p);
|
||||||
p->pChunk = 0;
|
p->pChunk = 0;
|
||||||
p->db = db;
|
p->db = db;
|
||||||
p->pEntry = 0;
|
p->pEntry = 0;
|
||||||
p->pLast = 0;
|
p->pLast = 0;
|
||||||
p->pForest = 0;
|
p->pForest = 0;
|
||||||
p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
|
p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
|
||||||
p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
|
p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
|
||||||
p->rsFlags = ROWSET_SORTED;
|
p->rsFlags = ROWSET_SORTED;
|
||||||
p->iBatch = 0;
|
p->iBatch = 0;
|
||||||
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +149,8 @@ RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
|
|||||||
** the RowSet has allocated over its lifetime. This routine is
|
** the RowSet has allocated over its lifetime. This routine is
|
||||||
** the destructor for the RowSet.
|
** the destructor for the RowSet.
|
||||||
*/
|
*/
|
||||||
void sqlite3RowSetClear(RowSet *p){
|
void sqlite3RowSetClear(void *pArg){
|
||||||
|
RowSet *p = (RowSet*)pArg;
|
||||||
struct RowSetChunk *pChunk, *pNextChunk;
|
struct RowSetChunk *pChunk, *pNextChunk;
|
||||||
for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){
|
for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){
|
||||||
pNextChunk = pChunk->pNextChunk;
|
pNextChunk = pChunk->pNextChunk;
|
||||||
@ -170,6 +164,16 @@ void sqlite3RowSetClear(RowSet *p){
|
|||||||
p->rsFlags = ROWSET_SORTED;
|
p->rsFlags = ROWSET_SORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Deallocate all chunks from a RowSet. This frees all memory that
|
||||||
|
** the RowSet has allocated over its lifetime. This routine is
|
||||||
|
** the destructor for the RowSet.
|
||||||
|
*/
|
||||||
|
void sqlite3RowSetDelete(void *pArg){
|
||||||
|
sqlite3RowSetClear(pArg);
|
||||||
|
sqlite3DbFree(((RowSet*)pArg)->db, pArg);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Allocate a new RowSetEntry object that is associated with the
|
** Allocate a new RowSetEntry object that is associated with the
|
||||||
** given RowSet. Return a pointer to the new and completely uninitialized
|
** given RowSet. Return a pointer to the new and completely uninitialized
|
||||||
|
@ -3825,8 +3825,9 @@ u32 sqlite3BitvecSize(Bitvec*);
|
|||||||
int sqlite3BitvecBuiltinTest(int,int*);
|
int sqlite3BitvecBuiltinTest(int,int*);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int);
|
RowSet *sqlite3RowSetInit(sqlite3*);
|
||||||
void sqlite3RowSetClear(RowSet*);
|
void sqlite3RowSetDelete(void*);
|
||||||
|
void sqlite3RowSetClear(void*);
|
||||||
void sqlite3RowSetInsert(RowSet*, i64);
|
void sqlite3RowSetInsert(RowSet*, i64);
|
||||||
int sqlite3RowSetTest(RowSet*, int iBatch, i64);
|
int sqlite3RowSetTest(RowSet*, int iBatch, i64);
|
||||||
int sqlite3RowSetNext(RowSet*, i64*);
|
int sqlite3RowSetNext(RowSet*, i64*);
|
||||||
|
26
src/vdbe.c
26
src/vdbe.c
@ -502,7 +502,7 @@ static void memTracePrint(Mem *p){
|
|||||||
}else if( p->flags & MEM_Real ){
|
}else if( p->flags & MEM_Real ){
|
||||||
printf(" r:%g", p->u.r);
|
printf(" r:%g", p->u.r);
|
||||||
#endif
|
#endif
|
||||||
}else if( p->flags & MEM_RowSet ){
|
}else if( sqlite3VdbeMemIsRowSet(p) ){
|
||||||
printf(" (rowset)");
|
printf(" (rowset)");
|
||||||
}else{
|
}else{
|
||||||
char zBuf[200];
|
char zBuf[200];
|
||||||
@ -5903,11 +5903,11 @@ case OP_RowSetAdd: { /* in1, in2 */
|
|||||||
pIn1 = &aMem[pOp->p1];
|
pIn1 = &aMem[pOp->p1];
|
||||||
pIn2 = &aMem[pOp->p2];
|
pIn2 = &aMem[pOp->p2];
|
||||||
assert( (pIn2->flags & MEM_Int)!=0 );
|
assert( (pIn2->flags & MEM_Int)!=0 );
|
||||||
if( (pIn1->flags & MEM_RowSet)==0 ){
|
if( (pIn1->flags & MEM_Blob)==0 ){
|
||||||
sqlite3VdbeMemSetRowSet(pIn1);
|
if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem;
|
||||||
if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
|
|
||||||
}
|
}
|
||||||
sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i);
|
assert( sqlite3VdbeMemIsRowSet(pIn1) );
|
||||||
|
sqlite3RowSetInsert((RowSet*)pIn1->z, pIn2->u.i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5923,8 +5923,9 @@ case OP_RowSetRead: { /* jump, in1, out3 */
|
|||||||
i64 val;
|
i64 val;
|
||||||
|
|
||||||
pIn1 = &aMem[pOp->p1];
|
pIn1 = &aMem[pOp->p1];
|
||||||
if( (pIn1->flags & MEM_RowSet)==0
|
assert( (pIn1->flags & MEM_Blob)==0 || sqlite3VdbeMemIsRowSet(pIn1) );
|
||||||
|| sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0
|
if( (pIn1->flags & MEM_Blob)==0
|
||||||
|
|| sqlite3RowSetNext((RowSet*)pIn1->z, &val)==0
|
||||||
){
|
){
|
||||||
/* The boolean index is empty */
|
/* The boolean index is empty */
|
||||||
sqlite3VdbeMemSetNull(pIn1);
|
sqlite3VdbeMemSetNull(pIn1);
|
||||||
@ -5973,20 +5974,19 @@ case OP_RowSetTest: { /* jump, in1, in3 */
|
|||||||
/* If there is anything other than a rowset object in memory cell P1,
|
/* If there is anything other than a rowset object in memory cell P1,
|
||||||
** delete it now and initialize P1 with an empty rowset
|
** delete it now and initialize P1 with an empty rowset
|
||||||
*/
|
*/
|
||||||
if( (pIn1->flags & MEM_RowSet)==0 ){
|
if( (pIn1->flags & MEM_Blob)==0 ){
|
||||||
sqlite3VdbeMemSetRowSet(pIn1);
|
if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem;
|
||||||
if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
|
|
||||||
}
|
}
|
||||||
|
assert( sqlite3VdbeMemIsRowSet(pIn1) );
|
||||||
assert( pOp->p4type==P4_INT32 );
|
assert( pOp->p4type==P4_INT32 );
|
||||||
assert( iSet==-1 || iSet>=0 );
|
assert( iSet==-1 || iSet>=0 );
|
||||||
if( iSet ){
|
if( iSet ){
|
||||||
exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i);
|
exists = sqlite3RowSetTest((RowSet*)pIn1->z, iSet, pIn3->u.i);
|
||||||
VdbeBranchTaken(exists!=0,2);
|
VdbeBranchTaken(exists!=0,2);
|
||||||
if( exists ) goto jump_to_p2;
|
if( exists ) goto jump_to_p2;
|
||||||
}
|
}
|
||||||
if( iSet>=0 ){
|
if( iSet>=0 ){
|
||||||
sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
|
sqlite3RowSetInsert((RowSet*)pIn1->z, pIn3->u.i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,6 @@ struct sqlite3_value {
|
|||||||
int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */
|
int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */
|
||||||
const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
|
const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
|
||||||
FuncDef *pDef; /* Used only when flags==MEM_Agg */
|
FuncDef *pDef; /* Used only when flags==MEM_Agg */
|
||||||
RowSet *pRowSet; /* Used only when flags==MEM_RowSet */
|
|
||||||
} u;
|
} u;
|
||||||
u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
|
u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
|
||||||
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
|
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
|
||||||
@ -247,7 +246,7 @@ struct sqlite3_value {
|
|||||||
#define MEM_Real 0x0008 /* Value is a real number */
|
#define MEM_Real 0x0008 /* Value is a real number */
|
||||||
#define MEM_Blob 0x0010 /* Value is a BLOB */
|
#define MEM_Blob 0x0010 /* Value is a BLOB */
|
||||||
#define MEM_AffMask 0x001f /* Mask of affinity bits */
|
#define MEM_AffMask 0x001f /* Mask of affinity bits */
|
||||||
#define MEM_RowSet 0x0020 /* Value is a RowSet object */
|
/* Available 0x0020 */
|
||||||
/* Available 0x0040 */
|
/* Available 0x0040 */
|
||||||
#define MEM_Undefined 0x0080 /* Value is undefined */
|
#define MEM_Undefined 0x0080 /* Value is undefined */
|
||||||
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
|
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
|
||||||
@ -275,7 +274,7 @@ struct sqlite3_value {
|
|||||||
** that needs to be deallocated to avoid a leak.
|
** that needs to be deallocated to avoid a leak.
|
||||||
*/
|
*/
|
||||||
#define VdbeMemDynamic(X) \
|
#define VdbeMemDynamic(X) \
|
||||||
(((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet))!=0)
|
(((X)->flags&(MEM_Agg|MEM_Dyn))!=0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Clear any existing type flags from a Mem and replace them with f
|
** Clear any existing type flags from a Mem and replace them with f
|
||||||
@ -488,7 +487,10 @@ void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*));
|
|||||||
void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
|
void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
|
||||||
void sqlite3VdbeMemSetNull(Mem*);
|
void sqlite3VdbeMemSetNull(Mem*);
|
||||||
void sqlite3VdbeMemSetZeroBlob(Mem*,int);
|
void sqlite3VdbeMemSetZeroBlob(Mem*,int);
|
||||||
void sqlite3VdbeMemSetRowSet(Mem*);
|
#ifdef SQLITE_DEBUG
|
||||||
|
int sqlite3VdbeMemIsRowSet(const Mem*);
|
||||||
|
#endif
|
||||||
|
int sqlite3VdbeMemSetRowSet(Mem*);
|
||||||
int sqlite3VdbeMemMakeWriteable(Mem*);
|
int sqlite3VdbeMemMakeWriteable(Mem*);
|
||||||
int sqlite3VdbeMemStringify(Mem*, u8, u8);
|
int sqlite3VdbeMemStringify(Mem*, u8, u8);
|
||||||
i64 sqlite3VdbeIntValue(Mem*);
|
i64 sqlite3VdbeIntValue(Mem*);
|
||||||
|
@ -1663,7 +1663,7 @@ static void releaseMemArray(Mem *p, int N){
|
|||||||
testcase( p->flags & MEM_Dyn );
|
testcase( p->flags & MEM_Dyn );
|
||||||
testcase( p->xDel==sqlite3VdbeFrameMemDel );
|
testcase( p->xDel==sqlite3VdbeFrameMemDel );
|
||||||
testcase( p->flags & MEM_RowSet );
|
testcase( p->flags & MEM_RowSet );
|
||||||
if( p->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet) ){
|
if( p->flags&(MEM_Agg|MEM_Dyn) ){
|
||||||
sqlite3VdbeMemRelease(p);
|
sqlite3VdbeMemRelease(p);
|
||||||
}else if( p->szMalloc ){
|
}else if( p->szMalloc ){
|
||||||
sqlite3DbFreeNN(db, p->zMalloc);
|
sqlite3DbFreeNN(db, p->zMalloc);
|
||||||
@ -3991,7 +3991,7 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
|
|||||||
f1 = pMem1->flags;
|
f1 = pMem1->flags;
|
||||||
f2 = pMem2->flags;
|
f2 = pMem2->flags;
|
||||||
combined_flags = f1|f2;
|
combined_flags = f1|f2;
|
||||||
assert( (combined_flags & MEM_RowSet)==0 );
|
assert( !sqlite3VdbeMemIsRowSet(pMem1) && !sqlite3VdbeMemIsRowSet(pMem2) );
|
||||||
|
|
||||||
/* If one value is NULL, it is less than the other. If both values
|
/* If one value is NULL, it is less than the other. If both values
|
||||||
** are NULL, return 0.
|
** are NULL, return 0.
|
||||||
|
@ -42,8 +42,7 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
|
|||||||
|
|
||||||
if( p->flags & MEM_Null ){
|
if( p->flags & MEM_Null ){
|
||||||
/* Cannot be both MEM_Null and some other type */
|
/* Cannot be both MEM_Null and some other type */
|
||||||
assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob
|
assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 );
|
||||||
|MEM_RowSet|MEM_Agg))==0 );
|
|
||||||
|
|
||||||
/* If MEM_Null is set, then either the value is a pure NULL (the usual
|
/* If MEM_Null is set, then either the value is a pure NULL (the usual
|
||||||
** case) or it is a pointer set using sqlite3_bind_pointer() or
|
** case) or it is a pointer set using sqlite3_bind_pointer() or
|
||||||
@ -156,7 +155,7 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
|
|||||||
#ifndef SQLITE_OMIT_UTF16
|
#ifndef SQLITE_OMIT_UTF16
|
||||||
int rc;
|
int rc;
|
||||||
#endif
|
#endif
|
||||||
assert( (pMem->flags&MEM_RowSet)==0 );
|
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||||
assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
|
assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
|
||||||
|| desiredEnc==SQLITE_UTF16BE );
|
|| desiredEnc==SQLITE_UTF16BE );
|
||||||
if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
|
if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
|
||||||
@ -189,7 +188,7 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
|
|||||||
*/
|
*/
|
||||||
SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
|
SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
|
||||||
assert( sqlite3VdbeCheckMemInvariants(pMem) );
|
assert( sqlite3VdbeCheckMemInvariants(pMem) );
|
||||||
assert( (pMem->flags&MEM_RowSet)==0 );
|
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||||
testcase( pMem->db==0 );
|
testcase( pMem->db==0 );
|
||||||
|
|
||||||
/* If the bPreserve flag is set to true, then the memory cell must already
|
/* If the bPreserve flag is set to true, then the memory cell must already
|
||||||
@ -277,7 +276,7 @@ static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
|
|||||||
*/
|
*/
|
||||||
int sqlite3VdbeMemMakeWriteable(Mem *pMem){
|
int sqlite3VdbeMemMakeWriteable(Mem *pMem){
|
||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||||
assert( (pMem->flags&MEM_RowSet)==0 );
|
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||||
if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){
|
if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){
|
||||||
if( ExpandBlob(pMem) ) return SQLITE_NOMEM;
|
if( ExpandBlob(pMem) ) return SQLITE_NOMEM;
|
||||||
if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){
|
if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){
|
||||||
@ -302,7 +301,7 @@ int sqlite3VdbeMemExpandBlob(Mem *pMem){
|
|||||||
int nByte;
|
int nByte;
|
||||||
assert( pMem->flags & MEM_Zero );
|
assert( pMem->flags & MEM_Zero );
|
||||||
assert( pMem->flags&MEM_Blob );
|
assert( pMem->flags&MEM_Blob );
|
||||||
assert( (pMem->flags&MEM_RowSet)==0 );
|
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||||
|
|
||||||
/* Set nByte to the number of bytes required to store the expanded blob. */
|
/* Set nByte to the number of bytes required to store the expanded blob. */
|
||||||
@ -357,7 +356,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
|
|||||||
assert( !(fg&MEM_Zero) );
|
assert( !(fg&MEM_Zero) );
|
||||||
assert( !(fg&(MEM_Str|MEM_Blob)) );
|
assert( !(fg&(MEM_Str|MEM_Blob)) );
|
||||||
assert( fg&(MEM_Int|MEM_Real) );
|
assert( fg&(MEM_Int|MEM_Real) );
|
||||||
assert( (pMem->flags&MEM_RowSet)==0 );
|
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||||
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
|
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
|
||||||
|
|
||||||
|
|
||||||
@ -462,11 +461,8 @@ static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){
|
|||||||
testcase( p->flags & MEM_Dyn );
|
testcase( p->flags & MEM_Dyn );
|
||||||
}
|
}
|
||||||
if( p->flags&MEM_Dyn ){
|
if( p->flags&MEM_Dyn ){
|
||||||
assert( (p->flags&MEM_RowSet)==0 );
|
|
||||||
assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 );
|
assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 );
|
||||||
p->xDel((void *)p->z);
|
p->xDel((void *)p->z);
|
||||||
}else if( p->flags&MEM_RowSet ){
|
|
||||||
sqlite3RowSetClear(p->u.pRowSet);
|
|
||||||
}
|
}
|
||||||
p->flags = MEM_Null;
|
p->flags = MEM_Null;
|
||||||
}
|
}
|
||||||
@ -614,7 +610,7 @@ int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
|
|||||||
void sqlite3VdbeIntegerAffinity(Mem *pMem){
|
void sqlite3VdbeIntegerAffinity(Mem *pMem){
|
||||||
i64 ix;
|
i64 ix;
|
||||||
assert( pMem->flags & MEM_Real );
|
assert( pMem->flags & MEM_Real );
|
||||||
assert( (pMem->flags & MEM_RowSet)==0 );
|
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||||
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
|
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
|
||||||
|
|
||||||
@ -641,7 +637,7 @@ void sqlite3VdbeIntegerAffinity(Mem *pMem){
|
|||||||
*/
|
*/
|
||||||
int sqlite3VdbeMemIntegerify(Mem *pMem){
|
int sqlite3VdbeMemIntegerify(Mem *pMem){
|
||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||||
assert( (pMem->flags & MEM_RowSet)==0 );
|
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||||
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
|
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
|
||||||
|
|
||||||
pMem->u.i = sqlite3VdbeIntValue(pMem);
|
pMem->u.i = sqlite3VdbeIntValue(pMem);
|
||||||
@ -859,26 +855,36 @@ void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SQLITE_DEBUG
|
||||||
|
/*
|
||||||
|
** Return true if the Mem holds a RowSet object. This routine is intended
|
||||||
|
** for use inside of assert() statements.
|
||||||
|
*/
|
||||||
|
int sqlite3VdbeMemIsRowSet(const Mem *pMem){
|
||||||
|
return (pMem->flags&(MEM_Blob|MEM_Dyn))==(MEM_Blob|MEM_Dyn)
|
||||||
|
&& pMem->xDel==sqlite3RowSetDelete;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Delete any previous value and set the value of pMem to be an
|
** Delete any previous value and set the value of pMem to be an
|
||||||
** empty boolean index.
|
** empty boolean index.
|
||||||
|
**
|
||||||
|
** Return SQLITE_OK on success and SQLITE_NOMEM if a memory allocation
|
||||||
|
** error occurs.
|
||||||
*/
|
*/
|
||||||
void sqlite3VdbeMemSetRowSet(Mem *pMem){
|
int sqlite3VdbeMemSetRowSet(Mem *pMem){
|
||||||
sqlite3 *db = pMem->db;
|
sqlite3 *db = pMem->db;
|
||||||
|
RowSet *p;
|
||||||
assert( db!=0 );
|
assert( db!=0 );
|
||||||
assert( (pMem->flags & MEM_RowSet)==0 );
|
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||||
sqlite3VdbeMemRelease(pMem);
|
sqlite3VdbeMemRelease(pMem);
|
||||||
pMem->zMalloc = sqlite3DbMallocRawNN(db, 64);
|
p = sqlite3RowSetInit(db);
|
||||||
if( db->mallocFailed ){
|
if( p==0 ) return SQLITE_NOMEM;
|
||||||
pMem->flags = MEM_Null;
|
pMem->z = (char*)p;
|
||||||
pMem->szMalloc = 0;
|
pMem->flags = MEM_Blob|MEM_Dyn;
|
||||||
}else{
|
pMem->xDel = sqlite3RowSetDelete;
|
||||||
assert( pMem->zMalloc );
|
return SQLITE_OK;
|
||||||
pMem->szMalloc = sqlite3DbMallocSize(db, pMem->zMalloc);
|
|
||||||
pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, pMem->szMalloc);
|
|
||||||
assert( pMem->u.pRowSet!=0 );
|
|
||||||
pMem->flags = MEM_RowSet;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -946,7 +952,7 @@ static SQLITE_NOINLINE void vdbeClrCopy(Mem *pTo, const Mem *pFrom, int eType){
|
|||||||
sqlite3VdbeMemShallowCopy(pTo, pFrom, eType);
|
sqlite3VdbeMemShallowCopy(pTo, pFrom, eType);
|
||||||
}
|
}
|
||||||
void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
|
void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
|
||||||
assert( (pFrom->flags & MEM_RowSet)==0 );
|
assert( !sqlite3VdbeMemIsRowSet(pFrom) );
|
||||||
assert( pTo->db==pFrom->db );
|
assert( pTo->db==pFrom->db );
|
||||||
if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; }
|
if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; }
|
||||||
memcpy(pTo, pFrom, MEMCELLSIZE);
|
memcpy(pTo, pFrom, MEMCELLSIZE);
|
||||||
@ -964,7 +970,7 @@ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
|
|||||||
int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
|
int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
|
||||||
assert( (pFrom->flags & MEM_RowSet)==0 );
|
assert( !sqlite3VdbeMemIsRowSet(pFrom) );
|
||||||
if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
|
if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
|
||||||
memcpy(pTo, pFrom, MEMCELLSIZE);
|
memcpy(pTo, pFrom, MEMCELLSIZE);
|
||||||
pTo->flags &= ~MEM_Dyn;
|
pTo->flags &= ~MEM_Dyn;
|
||||||
@ -1022,7 +1028,7 @@ int sqlite3VdbeMemSetStr(
|
|||||||
u16 flags = 0; /* New value for pMem->flags */
|
u16 flags = 0; /* New value for pMem->flags */
|
||||||
|
|
||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||||
assert( (pMem->flags & MEM_RowSet)==0 );
|
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||||
|
|
||||||
/* If z is a NULL pointer, set pMem to contain an SQL NULL. */
|
/* If z is a NULL pointer, set pMem to contain an SQL NULL. */
|
||||||
if( !z ){
|
if( !z ){
|
||||||
@ -1144,7 +1150,7 @@ int sqlite3VdbeMemFromBtree(
|
|||||||
|
|
||||||
/* Note: the calls to BtreeKeyFetch() and DataFetch() below assert()
|
/* Note: the calls to BtreeKeyFetch() and DataFetch() below assert()
|
||||||
** that both the BtShared and database handle mutexes are held. */
|
** that both the BtShared and database handle mutexes are held. */
|
||||||
assert( (pMem->flags & MEM_RowSet)==0 );
|
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||||
zData = (char *)sqlite3BtreePayloadFetch(pCur, &available);
|
zData = (char *)sqlite3BtreePayloadFetch(pCur, &available);
|
||||||
assert( zData!=0 );
|
assert( zData!=0 );
|
||||||
|
|
||||||
@ -1168,7 +1174,7 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
|
|||||||
assert( pVal!=0 );
|
assert( pVal!=0 );
|
||||||
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
|
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
|
||||||
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
|
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
|
||||||
assert( (pVal->flags & MEM_RowSet)==0 );
|
assert( !sqlite3VdbeMemIsRowSet(pVal) );
|
||||||
assert( (pVal->flags & (MEM_Null))==0 );
|
assert( (pVal->flags & (MEM_Null))==0 );
|
||||||
if( pVal->flags & (MEM_Blob|MEM_Str) ){
|
if( pVal->flags & (MEM_Blob|MEM_Str) ){
|
||||||
if( ExpandBlob(pVal) ) return 0;
|
if( ExpandBlob(pVal) ) return 0;
|
||||||
@ -1211,7 +1217,7 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
|
|||||||
if( !pVal ) return 0;
|
if( !pVal ) return 0;
|
||||||
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
|
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
|
||||||
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
|
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
|
||||||
assert( (pVal->flags & MEM_RowSet)==0 );
|
assert( !sqlite3VdbeMemIsRowSet(pVal) );
|
||||||
if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
|
if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
|
||||||
assert( sqlite3VdbeMemConsistentDualRep(pVal) );
|
assert( sqlite3VdbeMemConsistentDualRep(pVal) );
|
||||||
return pVal->z;
|
return pVal->z;
|
||||||
|
Loading…
Reference in New Issue
Block a user