mirror of https://github.com/sqlite/sqlite
In the sqlite3_context object, keep a pointer to the result value rather
than storing the result value in the sqlite3_context object and using memcpy() to move the value back into its register after the function returns. This runs faster and saves over 500 bytes of code space. FossilOrigin-Name: 6c1ee3e388eb110de815270467b1e50592c0ba6c
This commit is contained in:
parent
6c9f8e67de
commit
9bd038f12e
18
manifest
18
manifest
|
@ -1,5 +1,5 @@
|
|||
C Factor\sout\sthe\sexception\spaths\sfrom\ssqlite3ValueToText()\sinto\sa\sseparate\nfunction\sso\sthat\sthe\smain\sroutine\sis\smuch\sfaster\sfor\sthe\scommon\scase\sof\nno\srequired\stype\sor\sencoding\sconversions.
|
||||
D 2014-08-27T03:28:50.316
|
||||
C In\sthe\ssqlite3_context\sobject,\skeep\sa\spointer\sto\sthe\sresult\svalue\srather\nthan\sstoring\sthe\sresult\svalue\sin\sthe\ssqlite3_context\sobject\sand\susing\nmemcpy()\sto\smove\sthe\svalue\sback\sinto\sits\sregister\nafter\sthe\sfunction\sreturns.\s\sThis\sruns\sfaster\sand\ssaves\sover\s500\sbytes\nof\scode\sspace.
|
||||
D 2014-08-27T14:14:06.320
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
|
@ -284,13 +284,13 @@ F src/update.c ea336ce7b8b3fc5e316ba8f082e6445babf81059
|
|||
F src/utf.c 77abb5e6d27f3d236e50f7c8fff1d00e15262359
|
||||
F src/util.c 068dcd26354a3898ccc64ad5c4bdb95a7a15d33a
|
||||
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
|
||||
F src/vdbe.c 2f8fbc520cac2f5bacc43de2aeed6a4880c9cb57
|
||||
F src/vdbe.c 8b6638420347e01f7be6c276726441579a407be0
|
||||
F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8
|
||||
F src/vdbeInt.h df58400454823954cfb241e5858f07f37fc1fd78
|
||||
F src/vdbeapi.c cda974083d7597f807640d344ffcf76d872201ce
|
||||
F src/vdbeInt.h 4653bb420abb7acdc215659cdcedd3a59f336191
|
||||
F src/vdbeapi.c 09677a53dd8c71bcd670b0bd073bb9aefa02b441
|
||||
F src/vdbeaux.c dba006f67c9fd1b1d07ee7fb0fb38aa1905161d1
|
||||
F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4
|
||||
F src/vdbemem.c 9fc61d0860fd23399715fc436b2645154df08ce8
|
||||
F src/vdbemem.c 921d5468a68ac06f369810992e84ca22cc730a62
|
||||
F src/vdbesort.c f7f5563bf7d4695ca8f3203f3bf9de96d04ed0b3
|
||||
F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767
|
||||
F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f
|
||||
|
@ -1188,7 +1188,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P f94cacc393e895522b92c9717c53357afc918d60
|
||||
R 0d26b1eecc3f76fc31005918debb0d62
|
||||
P 1624916c6e9bc5dbcfa146b316a99ac8fecb13a9
|
||||
R d81ba05103ba02a6e3d94271217446d4
|
||||
U drh
|
||||
Z 03245edbdb5b11cf6bf42be492d2d8e5
|
||||
Z 3300f3f8d44a1fbcab3339e234a49760
|
||||
|
|
|
@ -1 +1 @@
|
|||
1624916c6e9bc5dbcfa146b316a99ac8fecb13a9
|
||||
6c1ee3e388eb110de815270467b1e50592c0ba6c
|
82
src/vdbe.c
82
src/vdbe.c
|
@ -1545,8 +1545,8 @@ case OP_Function: {
|
|||
apVal = p->apArg;
|
||||
assert( apVal || n==0 );
|
||||
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
|
||||
pOut = &aMem[pOp->p3];
|
||||
memAboutToChange(p, pOut);
|
||||
ctx.pOut = &aMem[pOp->p3];
|
||||
memAboutToChange(p, ctx.pOut);
|
||||
|
||||
assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
|
||||
assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
|
||||
|
@ -1562,16 +1562,7 @@ case OP_Function: {
|
|||
ctx.pFunc = pOp->p4.pFunc;
|
||||
ctx.iOp = pc;
|
||||
ctx.pVdbe = p;
|
||||
|
||||
/* The output cell may already have a buffer allocated. Move
|
||||
** the pointer to ctx.s so in case the user-function can use
|
||||
** the already allocated buffer instead of allocating a new one.
|
||||
*/
|
||||
memcpy(&ctx.s, pOut, sizeof(Mem));
|
||||
pOut->flags = MEM_Null;
|
||||
pOut->xDel = 0;
|
||||
pOut->zMalloc = 0;
|
||||
MemSetTypeFlag(&ctx.s, MEM_Null);
|
||||
MemSetTypeFlag(ctx.pOut, MEM_Null);
|
||||
|
||||
ctx.fErrorOrAux = 0;
|
||||
if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
|
||||
|
@ -1584,43 +1575,23 @@ case OP_Function: {
|
|||
(*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
|
||||
lastRowid = db->lastRowid;
|
||||
|
||||
if( db->mallocFailed ){
|
||||
/* Even though a malloc() has failed, the implementation of the
|
||||
** user function may have called an sqlite3_result_XXX() function
|
||||
** to return a value. The following call releases any resources
|
||||
** associated with such a value.
|
||||
*/
|
||||
sqlite3VdbeMemRelease(&ctx.s);
|
||||
goto no_mem;
|
||||
}
|
||||
|
||||
/* If the function returned an error, throw an exception */
|
||||
if( ctx.fErrorOrAux ){
|
||||
if( ctx.isError ){
|
||||
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
|
||||
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
|
||||
rc = ctx.isError;
|
||||
}
|
||||
sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
|
||||
}
|
||||
|
||||
/* Copy the result of the function into register P3 */
|
||||
sqlite3VdbeChangeEncoding(&ctx.s, encoding);
|
||||
assert( pOut->flags==MEM_Null );
|
||||
memcpy(pOut, &ctx.s, sizeof(Mem));
|
||||
if( sqlite3VdbeMemTooBig(pOut) ){
|
||||
sqlite3VdbeChangeEncoding(ctx.pOut, encoding);
|
||||
if( sqlite3VdbeMemTooBig(ctx.pOut) ){
|
||||
goto too_big;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* The app-defined function has done something that as caused this
|
||||
** statement to expire. (Perhaps the function called sqlite3_exec()
|
||||
** with a CREATE TABLE statement.)
|
||||
*/
|
||||
if( p->expired ) rc = SQLITE_ABORT;
|
||||
#endif
|
||||
|
||||
REGISTER_TRACE(pOp->p3, pOut);
|
||||
UPDATE_MAX_BLOBSIZE(pOut);
|
||||
REGISTER_TRACE(pOp->p3, ctx.pOut);
|
||||
UPDATE_MAX_BLOBSIZE(ctx.pOut);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -5610,6 +5581,7 @@ case OP_AggStep: {
|
|||
int i;
|
||||
Mem *pMem;
|
||||
Mem *pRec;
|
||||
Mem t;
|
||||
sqlite3_context ctx;
|
||||
sqlite3_value **apVal;
|
||||
|
||||
|
@ -5627,11 +5599,12 @@ case OP_AggStep: {
|
|||
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
|
||||
ctx.pMem = pMem = &aMem[pOp->p3];
|
||||
pMem->n++;
|
||||
ctx.s.flags = MEM_Null;
|
||||
ctx.s.z = 0;
|
||||
ctx.s.zMalloc = 0;
|
||||
ctx.s.xDel = 0;
|
||||
ctx.s.db = db;
|
||||
t.flags = MEM_Null;
|
||||
t.z = 0;
|
||||
t.zMalloc = 0;
|
||||
t.xDel = 0;
|
||||
t.db = db;
|
||||
ctx.pOut = &t;
|
||||
ctx.isError = 0;
|
||||
ctx.pColl = 0;
|
||||
ctx.skipFlag = 0;
|
||||
|
@ -5643,7 +5616,7 @@ case OP_AggStep: {
|
|||
}
|
||||
(ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
|
||||
if( ctx.isError ){
|
||||
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
|
||||
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t));
|
||||
rc = ctx.isError;
|
||||
}
|
||||
if( ctx.skipFlag ){
|
||||
|
@ -5651,9 +5624,7 @@ case OP_AggStep: {
|
|||
i = pOp[-1].p1;
|
||||
if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
|
||||
}
|
||||
|
||||
sqlite3VdbeMemRelease(&ctx.s);
|
||||
|
||||
sqlite3VdbeMemRelease(&t);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -6103,27 +6074,14 @@ case OP_VColumn: {
|
|||
pModule = pVtab->pModule;
|
||||
assert( pModule->xColumn );
|
||||
memset(&sContext, 0, sizeof(sContext));
|
||||
|
||||
/* The output cell may already have a buffer allocated. Move
|
||||
** the current contents to sContext.s so in case the user-function
|
||||
** can use the already allocated buffer instead of allocating a
|
||||
** new one.
|
||||
*/
|
||||
sqlite3VdbeMemMove(&sContext.s, pDest);
|
||||
MemSetTypeFlag(&sContext.s, MEM_Null);
|
||||
|
||||
sContext.pOut = pDest;
|
||||
MemSetTypeFlag(pDest, MEM_Null);
|
||||
rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
|
||||
sqlite3VtabImportErrmsg(p, pVtab);
|
||||
if( sContext.isError ){
|
||||
rc = sContext.isError;
|
||||
}
|
||||
|
||||
/* Copy the result of the function to the P3 register. We
|
||||
** do this regardless of whether or not an error occurred to ensure any
|
||||
** dynamic allocation in sContext.s (a Mem struct) is released.
|
||||
*/
|
||||
sqlite3VdbeChangeEncoding(&sContext.s, encoding);
|
||||
sqlite3VdbeMemMove(pDest, &sContext.s);
|
||||
sqlite3VdbeChangeEncoding(pDest, encoding);
|
||||
REGISTER_TRACE(pOp->p3, pDest);
|
||||
UPDATE_MAX_BLOBSIZE(pDest);
|
||||
|
||||
|
|
|
@ -266,8 +266,8 @@ struct AuxData {
|
|||
** (Mem) which are only defined there.
|
||||
*/
|
||||
struct sqlite3_context {
|
||||
Mem *pOut; /* The return value is stored here */
|
||||
FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */
|
||||
Mem s; /* The return value is stored here */
|
||||
Mem *pMem; /* Memory cell used to store aggregate context */
|
||||
CollSeq *pColl; /* Collating sequence */
|
||||
Vdbe *pVdbe; /* The VM that owns this context */
|
||||
|
|
|
@ -223,7 +223,7 @@ static void setResultStrOrError(
|
|||
u8 enc, /* Encoding of z. 0 for BLOBs */
|
||||
void (*xDel)(void*) /* Destructor function */
|
||||
){
|
||||
if( sqlite3VdbeMemSetStr(&pCtx->s, z, n, enc, xDel)==SQLITE_TOOBIG ){
|
||||
if( sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel)==SQLITE_TOOBIG ){
|
||||
sqlite3_result_error_toobig(pCtx);
|
||||
}
|
||||
}
|
||||
|
@ -234,38 +234,38 @@ void sqlite3_result_blob(
|
|||
void (*xDel)(void *)
|
||||
){
|
||||
assert( n>=0 );
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
setResultStrOrError(pCtx, z, n, 0, xDel);
|
||||
}
|
||||
void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
sqlite3VdbeMemSetDouble(pCtx->pOut, rVal);
|
||||
}
|
||||
void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
pCtx->isError = SQLITE_ERROR;
|
||||
pCtx->fErrorOrAux = 1;
|
||||
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
|
||||
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
pCtx->isError = SQLITE_ERROR;
|
||||
pCtx->fErrorOrAux = 1;
|
||||
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
|
||||
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
|
||||
}
|
||||
#endif
|
||||
void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal);
|
||||
}
|
||||
void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetInt64(&pCtx->s, iVal);
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
sqlite3VdbeMemSetInt64(pCtx->pOut, iVal);
|
||||
}
|
||||
void sqlite3_result_null(sqlite3_context *pCtx){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetNull(&pCtx->s);
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
sqlite3VdbeMemSetNull(pCtx->pOut);
|
||||
}
|
||||
void sqlite3_result_text(
|
||||
sqlite3_context *pCtx,
|
||||
|
@ -273,7 +273,7 @@ void sqlite3_result_text(
|
|||
int n,
|
||||
void (*xDel)(void *)
|
||||
){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
|
@ -283,7 +283,7 @@ void sqlite3_result_text16(
|
|||
int n,
|
||||
void (*xDel)(void *)
|
||||
){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel);
|
||||
}
|
||||
void sqlite3_result_text16be(
|
||||
|
@ -292,7 +292,7 @@ void sqlite3_result_text16be(
|
|||
int n,
|
||||
void (*xDel)(void *)
|
||||
){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel);
|
||||
}
|
||||
void sqlite3_result_text16le(
|
||||
|
@ -301,43 +301,43 @@ void sqlite3_result_text16le(
|
|||
int n,
|
||||
void (*xDel)(void *)
|
||||
){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel);
|
||||
}
|
||||
#endif /* SQLITE_OMIT_UTF16 */
|
||||
void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemCopy(&pCtx->s, pValue);
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
sqlite3VdbeMemCopy(pCtx->pOut, pValue);
|
||||
}
|
||||
void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetZeroBlob(&pCtx->s, n);
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n);
|
||||
}
|
||||
void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
|
||||
pCtx->isError = errCode;
|
||||
pCtx->fErrorOrAux = 1;
|
||||
if( pCtx->s.flags & MEM_Null ){
|
||||
sqlite3VdbeMemSetStr(&pCtx->s, sqlite3ErrStr(errCode), -1,
|
||||
if( pCtx->pOut->flags & MEM_Null ){
|
||||
sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1,
|
||||
SQLITE_UTF8, SQLITE_STATIC);
|
||||
}
|
||||
}
|
||||
|
||||
/* Force an SQLITE_TOOBIG error. */
|
||||
void sqlite3_result_error_toobig(sqlite3_context *pCtx){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
pCtx->isError = SQLITE_TOOBIG;
|
||||
pCtx->fErrorOrAux = 1;
|
||||
sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1,
|
||||
sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1,
|
||||
SQLITE_UTF8, SQLITE_STATIC);
|
||||
}
|
||||
|
||||
/* An SQLITE_NOMEM error. */
|
||||
void sqlite3_result_error_nomem(sqlite3_context *pCtx){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetNull(&pCtx->s);
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
sqlite3VdbeMemSetNull(pCtx->pOut);
|
||||
pCtx->isError = SQLITE_NOMEM;
|
||||
pCtx->fErrorOrAux = 1;
|
||||
pCtx->s.db->mallocFailed = 1;
|
||||
pCtx->pOut->db->mallocFailed = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -568,7 +568,7 @@ void *sqlite3_user_data(sqlite3_context *p){
|
|||
*/
|
||||
sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
|
||||
assert( p && p->pFunc );
|
||||
return p->s.db;
|
||||
return p->pOut->db;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -578,7 +578,7 @@ sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){
|
|||
Vdbe *v = p->pVdbe;
|
||||
int rc;
|
||||
if( v->iCurrentTime==0 ){
|
||||
rc = sqlite3OsCurrentTimeInt64(p->s.db->pVfs, &v->iCurrentTime);
|
||||
rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, &v->iCurrentTime);
|
||||
if( rc ) v->iCurrentTime = 0;
|
||||
}
|
||||
return v->iCurrentTime;
|
||||
|
@ -635,7 +635,7 @@ static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){
|
|||
*/
|
||||
void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
|
||||
assert( p && p->pFunc && p->pFunc->xStep );
|
||||
assert( sqlite3_mutex_held(p->s.db->mutex) );
|
||||
assert( sqlite3_mutex_held(p->pOut->db->mutex) );
|
||||
testcase( nByte<0 );
|
||||
if( (p->pMem->flags & MEM_Agg)==0 ){
|
||||
return createAggContext(p, nByte);
|
||||
|
@ -651,7 +651,7 @@ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
|
|||
void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
|
||||
AuxData *pAuxData;
|
||||
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
|
||||
if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
|
||||
}
|
||||
|
@ -673,7 +673,7 @@ void sqlite3_set_auxdata(
|
|||
AuxData *pAuxData;
|
||||
Vdbe *pVdbe = pCtx->pVdbe;
|
||||
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
if( iArg<0 ) goto failed;
|
||||
|
||||
for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
|
||||
|
|
|
@ -290,17 +290,20 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
|
|||
int rc = SQLITE_OK;
|
||||
if( ALWAYS(pFunc && pFunc->xFinalize) ){
|
||||
sqlite3_context ctx;
|
||||
Mem t;
|
||||
assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
ctx.s.flags = MEM_Null;
|
||||
ctx.s.db = pMem->db;
|
||||
memset(&t, 0, sizeof(t));
|
||||
t.flags = MEM_Null;
|
||||
t.db = pMem->db;
|
||||
ctx.pOut = &t;
|
||||
ctx.pMem = pMem;
|
||||
ctx.pFunc = pFunc;
|
||||
pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
|
||||
assert( 0==(pMem->flags&MEM_Dyn) && !pMem->xDel );
|
||||
sqlite3DbFree(pMem->db, pMem->zMalloc);
|
||||
memcpy(pMem, &ctx.s, sizeof(ctx.s));
|
||||
memcpy(pMem, &t, sizeof(t));
|
||||
rc = ctx.isError;
|
||||
}
|
||||
return rc;
|
||||
|
@ -615,14 +618,28 @@ void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** The pMem is known to contain content that needs to be destroyed prior
|
||||
** to a value change. So invoke the destructor, then set the value to
|
||||
** a 64-bit integer.
|
||||
*/
|
||||
static SQLITE_NOINLINE void vdbeReleaseAndSetInt64(Mem *pMem, i64 val){
|
||||
sqlite3VdbeMemReleaseExternal(pMem);
|
||||
pMem->u.i = val;
|
||||
pMem->flags = MEM_Int;
|
||||
}
|
||||
|
||||
/*
|
||||
** 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;
|
||||
if( VdbeMemDynamic(pMem) ){
|
||||
vdbeReleaseAndSetInt64(pMem, val);
|
||||
}else{
|
||||
pMem->u.i = val;
|
||||
pMem->flags = MEM_Int;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
|
|
Loading…
Reference in New Issue