aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2022-04-01 15:31:58 +0000
committerdrh <>2022-04-01 15:31:58 +0000
commit659fdb4da87b3eed2e5b5ec6369f63c34f682e2a (patch)
tree7330a3f93b5a88a91365f20490fc8d68ea9f95bb /src
parentc4c0ff86643edcd3f87d14f41e92f967af8a84c8 (diff)
downloadsqlite-659fdb4da87b3eed2e5b5ec6369f63c34f682e2a.tar.gz
sqlite-659fdb4da87b3eed2e5b5ec6369f63c34f682e2a.zip
Have the sqlite3_context object carry the encoding for the prepared statement
that it represents, so that sqlite3_result() and similar can set the encoding according to the prepared statement, even if the database encoding has changed. dbsqlfuzz c409b10d0a6bccf78ab00f47e1d29d42ee5b3565 FossilOrigin-Name: d4e19314f564126e180e091f9135c7bc55a10442edb46fbd3a4cfad21201dfa6
Diffstat (limited to 'src')
-rw-r--r--src/vdbe.c3
-rw-r--r--src/vdbeInt.h1
-rw-r--r--src/vdbeapi.c4
-rw-r--r--src/vdbemem.c3
4 files changed, 9 insertions, 2 deletions
diff --git a/src/vdbe.c b/src/vdbe.c
index ec227f884..138210943 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -7249,6 +7249,7 @@ case OP_AggStep: {
pCtx->pVdbe = p;
pCtx->skipFlag = 0;
pCtx->isError = 0;
+ pCtx->enc = encoding;
pCtx->argc = n;
pOp->p4type = P4_FUNCCTX;
pOp->p4.pCtx = pCtx;
@@ -7898,6 +7899,7 @@ case OP_VColumn: {
assert( pModule->xColumn );
memset(&sContext, 0, sizeof(sContext));
sContext.pOut = pDest;
+ sContext.enc = encoding;
assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 );
if( pOp->p5 & OPFLAG_NOCHNG ){
sqlite3VdbeMemSetNull(pDest);
@@ -8182,6 +8184,7 @@ case OP_Function: { /* group */
if( pCtx->pOut != pOut ){
pCtx->pVdbe = p;
pCtx->pOut = pOut;
+ pCtx->enc = encoding;
for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
}
assert( pCtx->pVdbe==p );
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index 45720b6a5..32c341eb8 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -369,6 +369,7 @@ struct sqlite3_context {
Vdbe *pVdbe; /* The VM that owns this context */
int iOp; /* Instruction number of OP_Function */
int isError; /* Error code returned by the function. */
+ u8 enc; /* Encoding to use for results */
u8 skipFlag; /* Skip accumulator loading if true */
u8 argc; /* Number of arguments */
sqlite3_value *argv[1]; /* Argument set */
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index 7567b8994..c23dd0e0c 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -391,7 +391,7 @@ static void setResultStrOrError(
}
return;
}
- sqlite3VdbeChangeEncoding(pOut, ENC(pOut->db));
+ sqlite3VdbeChangeEncoding(pOut, pCtx->enc);
if( sqlite3VdbeMemTooBig(pOut) ){
sqlite3_result_error_toobig(pCtx);
}
@@ -540,7 +540,7 @@ void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
Mem *pOut = pCtx->pOut;
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemCopy(pOut, pValue);
- sqlite3VdbeChangeEncoding(pOut, ENC(pOut->db));
+ sqlite3VdbeChangeEncoding(pOut, pCtx->enc);
if( sqlite3VdbeMemTooBig(pOut) ){
sqlite3_result_error_toobig(pCtx);
}
diff --git a/src/vdbemem.c b/src/vdbemem.c
index 82d79a580..5eac7cf71 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -467,6 +467,7 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
ctx.pOut = &t;
ctx.pMem = pMem;
ctx.pFunc = pFunc;
+ ctx.enc = ENC(t.db);
pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
assert( (pMem->flags & MEM_Dyn)==0 );
if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
@@ -494,6 +495,7 @@ int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){
ctx.pOut = pOut;
ctx.pMem = pAccum;
ctx.pFunc = pFunc;
+ ctx.enc = ENC(pAccum->db);
pFunc->xValue(&ctx);
return ctx.isError;
}
@@ -1491,6 +1493,7 @@ static int valueFromFunction(
memset(&ctx, 0, sizeof(ctx));
ctx.pOut = pVal;
ctx.pFunc = pFunc;
+ ctx.enc = ENC(db);
pFunc->xSFunc(&ctx, nVal, apVal);
if( ctx.isError ){
rc = ctx.isError;