mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-11 01:42:22 +03:00
Further improvements to large string handling in relation to JSON.
FossilOrigin-Name: 1e5df0aa3dae5cadbf1d07c718ae2a5212543300b68e49d35e8c96855a7f619c
This commit is contained in:
@@ -501,8 +501,8 @@ static void jsonAppendValue(
|
||||
*/
|
||||
static void jsonResult(JsonString *p){
|
||||
if( p->bErr==0 ){
|
||||
if( p->nAlloc>=p->nUsed+1 ) p->zBuf[p->nUsed] = 0;
|
||||
sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
|
||||
jsonAppendChar(p, 0);
|
||||
sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed-1,
|
||||
p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
|
||||
SQLITE_UTF8);
|
||||
jsonZero(p);
|
||||
|
||||
@@ -611,6 +611,7 @@ int sqlite3VdbeMemSetZeroBlob(Mem*,int);
|
||||
int sqlite3VdbeMemIsRowSet(const Mem*);
|
||||
#endif
|
||||
int sqlite3VdbeMemSetRowSet(Mem*);
|
||||
void sqlite3VdbeMemZeroTerminateIfAble(Mem*);
|
||||
int sqlite3VdbeMemMakeWriteable(Mem*);
|
||||
int sqlite3VdbeMemStringify(Mem*, u8, u8);
|
||||
int sqlite3IntFloatCompare(i64,double);
|
||||
|
||||
@@ -514,15 +514,7 @@ void sqlite3_result_text64(
|
||||
(void)invokeValueDestructor(z, xDel, pCtx);
|
||||
}else{
|
||||
setResultStrOrError(pCtx, z, (int)n, enc, xDel);
|
||||
if( xDel==sqlite3_free && enc==SQLITE_UTF8 ){
|
||||
Mem *pOut = pCtx->pOut;
|
||||
if( pOut->z==z
|
||||
&& sqlite3_msize(pOut->z) >= (sqlite3_uint64)(pOut->n+1)
|
||||
&& pOut->z[n]==0
|
||||
){
|
||||
pOut->flags |= MEM_Term;
|
||||
}
|
||||
}
|
||||
sqlite3VdbeMemZeroTerminateIfAble(pCtx->pOut);
|
||||
}
|
||||
}
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
|
||||
@@ -314,6 +314,32 @@ int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** If pMem is already a string, detect if it is a zero-terminated
|
||||
** string, or make it into one if possible, and mark it as such.
|
||||
**
|
||||
** This is an optimization. Correct operation continues even if
|
||||
** this routine is a no-op.
|
||||
*/
|
||||
void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){
|
||||
if( (pMem->flags & (MEM_Str|MEM_Term))!=MEM_Str ) return;
|
||||
if( pMem->enc!=SQLITE_UTF8 ) return;
|
||||
if( pMem->z==0 ) return;
|
||||
if( pMem->flags & MEM_Dyn ){
|
||||
if( pMem->xDel==sqlite3_free
|
||||
&& sqlite3_msize(pMem->z) >= pMem->n+1
|
||||
&& pMem->z[pMem->n]==0
|
||||
){
|
||||
pMem->flags |= MEM_Term;
|
||||
return;
|
||||
}
|
||||
}else if( pMem->szMalloc>0 && pMem->szMalloc >= pMem->n+1 ){
|
||||
pMem->z[pMem->n] = 0;
|
||||
pMem->flags |= MEM_Term;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** It is already known that pMem contains an unterminated string.
|
||||
** Add the zero terminator.
|
||||
@@ -803,6 +829,7 @@ int sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
int rc;
|
||||
assert( aff==SQLITE_AFF_TEXT );
|
||||
assert( MEM_Str==(MEM_Blob>>3) );
|
||||
pMem->flags |= (pMem->flags&MEM_Blob)>>3;
|
||||
@@ -810,7 +837,9 @@ int sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
|
||||
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
|
||||
pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
|
||||
if( encoding!=SQLITE_UTF8 ) pMem->n &= ~1;
|
||||
return sqlite3VdbeChangeEncoding(pMem, encoding);
|
||||
rc = sqlite3VdbeChangeEncoding(pMem, encoding);
|
||||
if( rc ) return rc;
|
||||
sqlite3VdbeMemZeroTerminateIfAble(pMem);
|
||||
}
|
||||
}
|
||||
return SQLITE_OK;
|
||||
|
||||
Reference in New Issue
Block a user