mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
When values have real affinity and are converted into strings for CHECK
constraints or index expressions, do the conversions into a real-number format even if the values are stored as integers for efficiency. This appears to fix ticket [ae0f637bddc5290b446]. FossilOrigin-Name: 5997d075665faca6b70fa647e877ebc84c473b32887b96235865d59ce80247f8
This commit is contained in:
18
manifest
18
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Fix\san\sincompatibility\swith\s-DSQLITE_OMIT_LOAD_EXTENSION=1\sin\sdbdata.test.
|
C When\svalues\shave\sreal\saffinity\sand\sare\sconverted\sinto\sstrings\sfor\sCHECK\nconstraints\sor\sindex\sexpressions,\sdo\sthe\sconversions\sinto\sa\sreal-number\sformat\neven\sif\sthe\svalues\sare\sstored\sas\sintegers\sfor\sefficiency.\nThis\sappears\sto\sfix\sticket\s[ae0f637bddc5290b446].
|
||||||
D 2019-05-01T17:36:56.822
|
D 2019-05-01T18:59:33.898
|
||||||
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 LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@@ -591,13 +591,13 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
|
|||||||
F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507
|
F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507
|
||||||
F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236
|
F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236
|
||||||
F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf
|
F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf
|
||||||
F src/vdbe.c 57b0b697d349876716499e073fb5e2d20ebc6cc0f752327a4e54031ed7e062f3
|
F src/vdbe.c c15d6a105c41db6a166b0aa9650829bdc0d92918a8926a92332ea1feb27c33ba
|
||||||
F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237
|
F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237
|
||||||
F src/vdbeInt.h 2c12704db9740c8e899786ecfc7a5797a9d067563496eb1b6ed03c592d7b8d90
|
F src/vdbeInt.h 0e2c44958fb42d90a4eacb122d77e2d5b89b82f5e2b4b047b422962dc0346357
|
||||||
F src/vdbeapi.c 2ddd60f4a351f15ee98d841e346af16111ad59dfa4d25d2dd4012e9875bf7d92
|
F src/vdbeapi.c 2ddd60f4a351f15ee98d841e346af16111ad59dfa4d25d2dd4012e9875bf7d92
|
||||||
F src/vdbeaux.c f873b5c2efcf8a4d6ecfc5b1a5b06fd810419198f3bd882175d371cc03801873
|
F src/vdbeaux.c f873b5c2efcf8a4d6ecfc5b1a5b06fd810419198f3bd882175d371cc03801873
|
||||||
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
|
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
|
||||||
F src/vdbemem.c dd2ee49255c4c5450f2b0887ef44cea8faa1cd7a46501b39a1a82b113ae418e3
|
F src/vdbemem.c df36fd36c7585e42869f3a44f5da5dc70e13306bc97ba52eebe069e174ba55db
|
||||||
F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47
|
F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47
|
||||||
F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
|
F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
|
||||||
F src/vtab.c 1fa256c6ddad7a81e2a4dc080d015d4b0a7135767717d311298e47f6fca64bb3
|
F src/vtab.c 1fa256c6ddad7a81e2a4dc080d015d4b0a7135767717d311298e47f6fca64bb3
|
||||||
@@ -1822,7 +1822,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 2be1ed70df605663822d1afdde757f426ccf2ee38add8dc6b6bb4fc4d90a31dc
|
P a77cd85b1a8b86e71b511f05f8c67faa046d24a48684139d2f64e51249203411
|
||||||
R ae90daf9628470675bc89644e7eb21cd
|
R 24b657a2152d8497e843307e630b65a0
|
||||||
U dan
|
U drh
|
||||||
Z 1604ae08830baf499595804bc5cb5239
|
Z 532f184e0e66c8f742c69b40ffa2c03e
|
||||||
|
@@ -1 +1 @@
|
|||||||
a77cd85b1a8b86e71b511f05f8c67faa046d24a48684139d2f64e51249203411
|
5997d075665faca6b70fa647e877ebc84c473b32887b96235865d59ce80247f8
|
15
src/vdbe.c
15
src/vdbe.c
@@ -514,6 +514,8 @@ static void memTracePrint(Mem *p){
|
|||||||
printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
|
printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
|
||||||
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
|
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
|
||||||
printf(" si:%lld", p->u.i);
|
printf(" si:%lld", p->u.i);
|
||||||
|
}else if( (p->flags & (MEM_Int|MEM_IntReal))==(MEM_Int|MEM_IntReal) ){
|
||||||
|
printf(" ir:%lld", p->u.i);
|
||||||
}else if( p->flags & MEM_Int ){
|
}else if( p->flags & MEM_Int ){
|
||||||
printf(" i:%lld", p->u.i);
|
printf(" i:%lld", p->u.i);
|
||||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||||
@@ -2776,13 +2778,20 @@ case OP_Affinity: {
|
|||||||
assert( pOp->p2>0 );
|
assert( pOp->p2>0 );
|
||||||
assert( zAffinity[pOp->p2]==0 );
|
assert( zAffinity[pOp->p2]==0 );
|
||||||
pIn1 = &aMem[pOp->p1];
|
pIn1 = &aMem[pOp->p1];
|
||||||
do{
|
while( 1 /*edit-by-break*/ ){
|
||||||
assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
|
assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
|
||||||
assert( memIsValid(pIn1) );
|
assert( memIsValid(pIn1) );
|
||||||
applyAffinity(pIn1, *(zAffinity++), encoding);
|
applyAffinity(pIn1, zAffinity[0], encoding);
|
||||||
|
if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){
|
||||||
|
/* When applying REAL affinity, if the result is still MEM_Int,
|
||||||
|
** indicate that REAL is actually desired */
|
||||||
|
pIn1->flags |= MEM_IntReal;
|
||||||
|
}
|
||||||
REGISTER_TRACE((int)(pIn1-aMem), pIn1);
|
REGISTER_TRACE((int)(pIn1-aMem), pIn1);
|
||||||
|
zAffinity++;
|
||||||
|
if( zAffinity[0]==0 ) break;
|
||||||
pIn1++;
|
pIn1++;
|
||||||
}while( zAffinity[0] );
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -247,7 +247,7 @@ struct sqlite3_value {
|
|||||||
#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_FromBind 0x0020 /* Value originates from sqlite3_bind() */
|
#define MEM_FromBind 0x0020 /* Value originates from sqlite3_bind() */
|
||||||
/* Available 0x0040 */
|
#define MEM_IntReal 0x0040 /* MEM_Int that stringifies like MEM_Real */
|
||||||
#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 */
|
||||||
#define MEM_TypeMask 0xc1df /* Mask of type bits */
|
#define MEM_TypeMask 0xc1df /* Mask of type bits */
|
||||||
|
@@ -92,6 +92,25 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Render a Mem object which is either MEM_Int or MEM_Real into a
|
||||||
|
** buffer.
|
||||||
|
*/
|
||||||
|
static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){
|
||||||
|
StrAccum acc;
|
||||||
|
assert( p->flags & (MEM_Int|MEM_Real) );
|
||||||
|
sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0);
|
||||||
|
if( p->flags & MEM_IntReal ){
|
||||||
|
sqlite3_str_appendf(&acc, "%!.15g", (double)p->u.i);
|
||||||
|
}else if( p->flags & MEM_Int ){
|
||||||
|
sqlite3_str_appendf(&acc, "%lld", p->u.i);
|
||||||
|
}else{
|
||||||
|
sqlite3_str_appendf(&acc, "%!.15g", p->u.r);
|
||||||
|
}
|
||||||
|
assert( acc.zText==zBuf && acc.mxAlloc<=0 );
|
||||||
|
zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
/*
|
/*
|
||||||
** Check that string value of pMem agrees with its integer or real value.
|
** Check that string value of pMem agrees with its integer or real value.
|
||||||
@@ -118,11 +137,7 @@ int sqlite3VdbeMemConsistentDualRep(Mem *p){
|
|||||||
int i, j, incr;
|
int i, j, incr;
|
||||||
if( (p->flags & MEM_Str)==0 ) return 1;
|
if( (p->flags & MEM_Str)==0 ) return 1;
|
||||||
if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1;
|
if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1;
|
||||||
if( p->flags & MEM_Int ){
|
vdbeMemRenderNum(sizeof(zBuf), zBuf, p);
|
||||||
sqlite3_snprintf(sizeof(zBuf),zBuf,"%lld",p->u.i);
|
|
||||||
}else{
|
|
||||||
sqlite3_snprintf(sizeof(zBuf),zBuf,"%!.15g",p->u.r);
|
|
||||||
}
|
|
||||||
z = p->z;
|
z = p->z;
|
||||||
i = j = 0;
|
i = j = 0;
|
||||||
incr = 1;
|
incr = 1;
|
||||||
@@ -248,7 +263,7 @@ int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
|
|||||||
}
|
}
|
||||||
assert( (pMem->flags & MEM_Dyn)==0 );
|
assert( (pMem->flags & MEM_Dyn)==0 );
|
||||||
pMem->z = pMem->zMalloc;
|
pMem->z = pMem->zMalloc;
|
||||||
pMem->flags &= (MEM_Null|MEM_Int|MEM_Real);
|
pMem->flags &= (MEM_Null|MEM_Int|MEM_Real|MEM_IntReal);
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,13 +364,12 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){
|
|||||||
** user and the latter is an internal programming error.
|
** user and the latter is an internal programming error.
|
||||||
*/
|
*/
|
||||||
int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
|
int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
|
||||||
int fg = pMem->flags;
|
|
||||||
const int nByte = 32;
|
const int nByte = 32;
|
||||||
|
|
||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||||
assert( !(fg&MEM_Zero) );
|
assert( !(pMem->flags&MEM_Zero) );
|
||||||
assert( !(fg&(MEM_Str|MEM_Blob)) );
|
assert( !(pMem->flags&(MEM_Str|MEM_Blob)) );
|
||||||
assert( fg&(MEM_Int|MEM_Real) );
|
assert( pMem->flags&(MEM_Int|MEM_Real) );
|
||||||
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||||
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
|
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
|
||||||
|
|
||||||
@@ -365,23 +379,12 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
|
|||||||
return SQLITE_NOMEM_BKPT;
|
return SQLITE_NOMEM_BKPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
|
vdbeMemRenderNum(nByte, pMem->z, pMem);
|
||||||
** string representation of the value. Then, if the required encoding
|
|
||||||
** is UTF-16le or UTF-16be do a translation.
|
|
||||||
**
|
|
||||||
** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
|
|
||||||
*/
|
|
||||||
if( fg & MEM_Int ){
|
|
||||||
sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
|
|
||||||
}else{
|
|
||||||
assert( fg & MEM_Real );
|
|
||||||
sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
|
|
||||||
}
|
|
||||||
assert( pMem->z!=0 );
|
assert( pMem->z!=0 );
|
||||||
pMem->n = sqlite3Strlen30NN(pMem->z);
|
pMem->n = sqlite3Strlen30NN(pMem->z);
|
||||||
pMem->enc = SQLITE_UTF8;
|
pMem->enc = SQLITE_UTF8;
|
||||||
pMem->flags |= MEM_Str|MEM_Term;
|
pMem->flags |= MEM_Str|MEM_Term;
|
||||||
if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
|
if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal);
|
||||||
sqlite3VdbeChangeEncoding(pMem, enc);
|
sqlite3VdbeChangeEncoding(pMem, enc);
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
@@ -741,7 +744,7 @@ void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
|
|||||||
pMem->flags |= (pMem->flags&MEM_Blob)>>3;
|
pMem->flags |= (pMem->flags&MEM_Blob)>>3;
|
||||||
sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
|
sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
|
||||||
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
|
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
|
||||||
pMem->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
|
pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user