Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch int-real Excluding Merge-Ins
This is equivalent to a diff from 48889530a9 to 8b8ef445cc
2019-05-04
| ||
01:41 | In the sqlite3_value or Mem object, make the MEM_IntReal type completely independent from MEM_Int and MEM_Real. This helps avoid problems when inserting non-float values into a "REAL" column. (check-in: 5a8a23ee5f user: drh tags: trunk) | |
01:29 | New testcase macros to ensure that MEM_IntReal is fully tested. (Closed-Leaf check-in: 8b8ef445cc user: drh tags: int-real) | |
2019-05-03
| ||
21:17 | Add the SQLITE_TESTCTRL_RESULT_INTREAL test-control and use it to create the intreal() SQL function in testfixture. Write a few simple tests to prove this all works. TH3 will hold most of the INTREAL tests, probably. (check-in: c983873132 user: drh tags: int-real) | |
02:41 | Fix the ".open --hexdb" command in the CLI so that it works even with terminal input. (check-in: 9b5d943426 user: drh tags: trunk) | |
2019-05-02
| ||
21:36 | Make MEM_IntReal a completely independent type, meaning a floating point value stored as an integer. This fixes a problem with arithmetic within arguments to string functions on indexes of expressions. But it is a big change and needs lots of new testcase() macros for MC/DC and so it is initially put on this branch. (check-in: dba836e31c user: drh tags: int-real) | |
17:45 | Ensure that the typeof() function always returns SQLITE_FLOAT for floating point values even when the value is stored as an integer to save space. (check-in: 48889530a9 user: drh tags: trunk) | |
17:06 | Add options to wapptest.tcl similar to those supported by releasetest.tcl. Also add the -noui switch, for running without wapp altogether. (check-in: 005a169406 user: dan tags: trunk) | |
Changes to src/main.c.
4100 4100 */ 4101 4101 case SQLITE_TESTCTRL_PARSER_COVERAGE: { 4102 4102 FILE *out = va_arg(ap, FILE*); 4103 4103 if( sqlite3ParserCoverage(out) ) rc = SQLITE_ERROR; 4104 4104 break; 4105 4105 } 4106 4106 #endif /* defined(YYCOVERAGE) */ 4107 + 4108 + /* sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, sqlite3_context*); 4109 + ** 4110 + ** This test-control causes the most recent sqlite3_result_int64() value 4111 + ** to be interpreted as a MEM_IntReal instead of as an MEM_Int. Normally, 4112 + ** MEM_IntReal values only arise during an INSERT operation of integer 4113 + ** values into a REAL column, so they can be challenging to test. This 4114 + ** test-control enables us to write an intreal() SQL function that can 4115 + ** inject an intreal() value at arbitrary places in an SQL statement, 4116 + ** for testing purposes. 4117 + */ 4118 + case SQLITE_TESTCTRL_RESULT_INTREAL: { 4119 + sqlite3_context *pCtx = va_arg(ap, sqlite3_context*); 4120 + sqlite3ResultIntReal(pCtx); 4121 + break; 4122 + } 4107 4123 } 4108 4124 va_end(ap); 4109 4125 #endif /* SQLITE_UNTESTABLE */ 4110 4126 return rc; 4111 4127 } 4112 4128 4113 4129 /*
Changes to src/sqlite.h.in.
7315 7315 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 7316 7316 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 7317 7317 #define SQLITE_TESTCTRL_BYTEORDER 22 7318 7318 #define SQLITE_TESTCTRL_ISINIT 23 7319 7319 #define SQLITE_TESTCTRL_SORTER_MMAP 24 7320 7320 #define SQLITE_TESTCTRL_IMPOSTER 25 7321 7321 #define SQLITE_TESTCTRL_PARSER_COVERAGE 26 7322 -#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */ 7322 +#define SQLITE_TESTCTRL_RESULT_INTREAL 27 7323 +#define SQLITE_TESTCTRL_LAST 27 /* Largest TESTCTRL */ 7323 7324 7324 7325 /* 7325 7326 ** CAPI3REF: SQL Keyword Checking 7326 7327 ** 7327 7328 ** These routines provide access to the set of SQL language keywords 7328 7329 ** recognized by SQLite. Applications can uses these routines to determine 7329 7330 ** whether or not a specific identifier needs to be escaped (for example,
Changes to src/sqliteInt.h.
4268 4268 4269 4269 const void *sqlite3ValueText(sqlite3_value*, u8); 4270 4270 int sqlite3ValueBytes(sqlite3_value*, u8); 4271 4271 void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, 4272 4272 void(*)(void*)); 4273 4273 void sqlite3ValueSetNull(sqlite3_value*); 4274 4274 void sqlite3ValueFree(sqlite3_value*); 4275 +#ifndef SQLITE_UNTESTABLE 4276 +void sqlite3ResultIntReal(sqlite3_context*); 4277 +#endif 4275 4278 sqlite3_value *sqlite3ValueNew(sqlite3 *); 4276 4279 #ifndef SQLITE_OMIT_UTF16 4277 4280 char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8); 4278 4281 #endif 4279 4282 int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); 4280 4283 void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); 4281 4284 #ifndef SQLITE_AMALGAMATION
Changes to src/test1.c.
993 993 sqlite3_context *context, 994 994 int argc, 995 995 sqlite3_value **argv 996 996 ){ 997 997 static int cnt = 0; 998 998 sqlite3_result_int(context, cnt++); 999 999 } 1000 + 1001 +/* 1002 +** This SQL function returns the integer value of its argument as a MEM_IntReal 1003 +** value. 1004 +*/ 1005 +static void intrealFunction( 1006 + sqlite3_context *context, 1007 + int argc, 1008 + sqlite3_value **argv 1009 +){ 1010 + sqlite3_int64 v = sqlite3_value_int64(argv[0]); 1011 + sqlite3_result_int64(context, v); 1012 + sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, context); 1013 +} 1000 1014 1001 1015 /* 1002 1016 ** Usage: sqlite3_create_function DB 1003 1017 ** 1004 1018 ** Call the sqlite3_create_function API on the given database in order 1005 1019 ** to create a function named "x_coalesce". This function does the same thing 1006 1020 ** as the "coalesce" function. This function also registers an SQL function ................................................................................ 1057 1071 rc = sqlite3_create_function(db, "counter1", -1, SQLITE_UTF8, 1058 1072 0, nondeterministicFunction, 0, 0); 1059 1073 } 1060 1074 if( rc==SQLITE_OK ){ 1061 1075 rc = sqlite3_create_function(db, "counter2", -1, SQLITE_UTF8|SQLITE_DETERMINISTIC, 1062 1076 0, nondeterministicFunction, 0, 0); 1063 1077 } 1078 + 1079 + /* The intreal() function converts its argument to an integer and returns 1080 + ** it as a MEM_IntReal. 1081 + */ 1082 + if( rc==SQLITE_OK ){ 1083 + rc = sqlite3_create_function(db, "intreal", 1, SQLITE_UTF8, 1084 + 0, intrealFunction, 0, 0); 1085 + } 1064 1086 1065 1087 #ifndef SQLITE_OMIT_UTF16 1066 1088 /* Use the sqlite3_create_function16() API here. Mainly for fun, but also 1067 1089 ** because it is not tested anywhere else. */ 1068 1090 if( rc==SQLITE_OK ){ 1069 1091 const void *zUtf16; 1070 1092 sqlite3_value *pVal;
Changes to src/vdbe.c.
291 291 ** point or exponential notation, the result is only MEM_Real, even 292 292 ** if there is an exact integer representation of the quantity. 293 293 */ 294 294 static void applyNumericAffinity(Mem *pRec, int bTryForInt){ 295 295 double rValue; 296 296 i64 iValue; 297 297 u8 enc = pRec->enc; 298 - assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str ); 298 + assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real|MEM_IntReal))==MEM_Str ); 299 299 if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; 300 300 if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ 301 301 pRec->u.i = iValue; 302 302 pRec->flags |= MEM_Int; 303 303 }else{ 304 304 pRec->u.r = rValue; 305 305 pRec->flags |= MEM_Real; ................................................................................ 348 348 }else if( affinity==SQLITE_AFF_TEXT ){ 349 349 /* Only attempt the conversion to TEXT if there is an integer or real 350 350 ** representation (blob and NULL do not get converted) but no string 351 351 ** representation. It would be harmless to repeat the conversion if 352 352 ** there is already a string rep, but it is pointless to waste those 353 353 ** CPU cycles. */ 354 354 if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/ 355 - if( (pRec->flags&(MEM_Real|MEM_Int)) ){ 355 + if( (pRec->flags&(MEM_Real|MEM_Int|MEM_IntReal)) ){ 356 + testcase( pRec->flags & MEM_Int ); 357 + testcase( pRec->flags & MEM_Real ); 358 + testcase( pRec->flags & MEM_IntReal ); 356 359 sqlite3VdbeMemStringify(pRec, enc, 1); 357 360 } 358 361 } 359 - pRec->flags &= ~(MEM_Real|MEM_Int); 362 + pRec->flags &= ~(MEM_Real|MEM_Int|MEM_IntReal); 360 363 } 361 364 } 362 365 363 366 /* 364 367 ** Try to convert the type of a function argument or a result column 365 368 ** into a numeric representation. Use either INTEGER or REAL whichever 366 369 ** is appropriate. But only do the conversion if it is possible without ................................................................................ 391 394 /* 392 395 ** pMem currently only holds a string type (or maybe a BLOB that we can 393 396 ** interpret as a string if we want to). Compute its corresponding 394 397 ** numeric type, if has one. Set the pMem->u.r and pMem->u.i fields 395 398 ** accordingly. 396 399 */ 397 400 static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ 398 - assert( (pMem->flags & (MEM_Int|MEM_Real))==0 ); 401 + assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ); 399 402 assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ); 400 403 ExpandBlob(pMem); 401 404 if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){ 402 405 return 0; 403 406 } 404 407 if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==0 ){ 405 408 return MEM_Int; ................................................................................ 411 414 ** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or 412 415 ** none. 413 416 ** 414 417 ** Unlike applyNumericAffinity(), this routine does not modify pMem->flags. 415 418 ** But it does set pMem->u.r and pMem->u.i appropriately. 416 419 */ 417 420 static u16 numericType(Mem *pMem){ 418 - if( pMem->flags & (MEM_Int|MEM_Real) ){ 419 - return pMem->flags & (MEM_Int|MEM_Real); 421 + if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal) ){ 422 + testcase( pMem->flags & MEM_Int ); 423 + testcase( pMem->flags & MEM_Real ); 424 + testcase( pMem->flags & MEM_IntReal ); 425 + return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal); 420 426 } 421 427 if( pMem->flags & (MEM_Str|MEM_Blob) ){ 428 + testcase( pMem->flags & MEM_Str ); 429 + testcase( pMem->flags & MEM_Blob ); 422 430 return computeNumericType(pMem); 423 431 } 424 432 return 0; 425 433 } 426 434 427 435 #ifdef SQLITE_DEBUG 428 436 /* ................................................................................ 510 518 static void memTracePrint(Mem *p){ 511 519 if( p->flags & MEM_Undefined ){ 512 520 printf(" undefined"); 513 521 }else if( p->flags & MEM_Null ){ 514 522 printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL"); 515 523 }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ 516 524 printf(" si:%lld", p->u.i); 517 - }else if( (p->flags & (MEM_Int|MEM_IntReal))==(MEM_Int|MEM_IntReal) ){ 525 + }else if( (p->flags & (MEM_IntReal))!=0 ){ 518 526 printf(" ir:%lld", p->u.i); 519 527 }else if( p->flags & MEM_Int ){ 520 528 printf(" i:%lld", p->u.i); 521 529 #ifndef SQLITE_OMIT_FLOATING_POINT 522 530 }else if( p->flags & MEM_Real ){ 523 531 printf(" r:%g", p->u.r); 524 532 #endif ................................................................................ 1626 1634 MemSetTypeFlag(pOut, MEM_Int); 1627 1635 #else 1628 1636 if( sqlite3IsNaN(rB) ){ 1629 1637 goto arithmetic_result_is_null; 1630 1638 } 1631 1639 pOut->u.r = rB; 1632 1640 MemSetTypeFlag(pOut, MEM_Real); 1633 - if( ((type1|type2)&MEM_Real)==0 && !bIntint ){ 1641 + if( ((type1|type2)&(MEM_Real|MEM_IntReal))==0 && !bIntint ){ 1634 1642 sqlite3VdbeIntegerAffinity(pOut); 1635 1643 } 1636 1644 #endif 1637 1645 } 1638 1646 break; 1639 1647 1640 1648 arithmetic_result_is_null: ................................................................................ 1797 1805 ** This opcode is used when extracting information from a column that 1798 1806 ** has REAL affinity. Such column values may still be stored as 1799 1807 ** integers, for space efficiency, but after extraction we want them 1800 1808 ** to have only a real value. 1801 1809 */ 1802 1810 case OP_RealAffinity: { /* in1 */ 1803 1811 pIn1 = &aMem[pOp->p1]; 1804 - if( pIn1->flags & MEM_Int ){ 1812 + if( pIn1->flags & (MEM_Int|MEM_IntReal) ){ 1813 + testcase( pIn1->flags & MEM_Int ); 1814 + testcase( pIn1->flags & MEM_IntReal ); 1805 1815 sqlite3VdbeMemRealify(pIn1); 1806 1816 } 1807 1817 break; 1808 1818 } 1809 1819 #endif 1810 1820 1811 1821 #ifndef SQLITE_OMIT_CAST ................................................................................ 1989 1999 break; 1990 2000 } 1991 2001 }else{ 1992 2002 /* Neither operand is NULL. Do a comparison. */ 1993 2003 affinity = pOp->p5 & SQLITE_AFF_MASK; 1994 2004 if( affinity>=SQLITE_AFF_NUMERIC ){ 1995 2005 if( (flags1 | flags3)&MEM_Str ){ 1996 - if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ 2006 + if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ 1997 2007 applyNumericAffinity(pIn1,0); 1998 2008 assert( flags3==pIn3->flags ); 1999 2009 /* testcase( flags3!=pIn3->flags ); 2000 2010 ** this used to be possible with pIn1==pIn3, but not since 2001 2011 ** the column cache was removed. The following assignment 2002 2012 ** is essentially a no-op. But, it provides defense-in-depth 2003 2013 ** in case our analysis is incorrect, so it is left in. */ 2004 2014 flags3 = pIn3->flags; 2005 2015 } 2006 - if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ 2016 + if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ 2007 2017 applyNumericAffinity(pIn3,0); 2008 2018 } 2009 2019 } 2010 2020 /* Handle the common case of integer comparison here, as an 2011 2021 ** optimization, to avoid a call to sqlite3MemCompare() */ 2012 2022 if( (pIn1->flags & pIn3->flags & MEM_Int)!=0 ){ 2013 2023 if( pIn3->u.i > pIn1->u.i ){ res = +1; goto compare_op; } 2014 2024 if( pIn3->u.i < pIn1->u.i ){ res = -1; goto compare_op; } 2015 2025 res = 0; 2016 2026 goto compare_op; 2017 2027 } 2018 2028 }else if( affinity==SQLITE_AFF_TEXT ){ 2019 - if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){ 2029 + if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ 2020 2030 testcase( pIn1->flags & MEM_Int ); 2021 2031 testcase( pIn1->flags & MEM_Real ); 2032 + testcase( pIn1->flags & MEM_IntReal ); 2022 2033 sqlite3VdbeMemStringify(pIn1, encoding, 1); 2023 2034 testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); 2024 2035 flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); 2025 2036 assert( pIn1!=pIn3 ); 2026 2037 } 2027 - if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){ 2038 + if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ 2028 2039 testcase( pIn3->flags & MEM_Int ); 2029 2040 testcase( pIn3->flags & MEM_Real ); 2041 + testcase( pIn3->flags & MEM_IntReal ); 2030 2042 sqlite3VdbeMemStringify(pIn3, encoding, 1); 2031 2043 testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) ); 2032 2044 flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask); 2033 2045 } 2034 2046 } 2035 2047 assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); 2036 2048 res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); ................................................................................ 2786 2798 assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] ); 2787 2799 assert( memIsValid(pIn1) ); 2788 2800 applyAffinity(pIn1, zAffinity[0], encoding); 2789 2801 if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){ 2790 2802 /* When applying REAL affinity, if the result is still MEM_Int, 2791 2803 ** indicate that REAL is actually desired */ 2792 2804 pIn1->flags |= MEM_IntReal; 2805 + pIn1->flags &= ~MEM_Int; 2793 2806 } 2794 2807 REGISTER_TRACE((int)(pIn1-aMem), pIn1); 2795 2808 zAffinity++; 2796 2809 if( zAffinity[0]==0 ) break; 2797 2810 pIn1++; 2798 2811 } 2799 2812 break; ................................................................................ 3983 3996 assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0 3984 3997 || CORRUPT_DB ); 3985 3998 3986 3999 /* The input value in P3 might be of any type: integer, real, string, 3987 4000 ** blob, or NULL. But it needs to be an integer before we can do 3988 4001 ** the seek, so convert it. */ 3989 4002 pIn3 = &aMem[pOp->p3]; 3990 - if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ 4003 + if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){ 3991 4004 applyNumericAffinity(pIn3, 0); 3992 4005 } 3993 4006 iKey = sqlite3VdbeIntValue(pIn3); 3994 4007 3995 4008 /* If the P3 value could not be converted into an integer without 3996 4009 ** loss of information, then special processing is required... */ 3997 - if( (pIn3->flags & MEM_Int)==0 ){ 4010 + if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){ 3998 4011 if( (pIn3->flags & MEM_Real)==0 ){ 3999 4012 /* If the P3 value cannot be converted into any kind of a number, 4000 4013 ** then the seek is not possible, so jump to P2 */ 4001 4014 VdbeBranchTaken(1,2); goto jump_to_p2; 4002 4015 break; 4003 4016 } 4004 4017 ................................................................................ 4375 4388 case OP_SeekRowid: { /* jump, in3 */ 4376 4389 VdbeCursor *pC; 4377 4390 BtCursor *pCrsr; 4378 4391 int res; 4379 4392 u64 iKey; 4380 4393 4381 4394 pIn3 = &aMem[pOp->p3]; 4382 - if( (pIn3->flags & MEM_Int)==0 ){ 4395 + testcase( pIn3->flags & MEM_Int ); 4396 + testcase( pIn3->flags & MEM_IntReal ); 4397 + if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){ 4383 4398 /* Make sure pIn3->u.i contains a valid integer representation of 4384 4399 ** the key value, but do not change the datatype of the register, as 4385 4400 ** other parts of the perpared statement might be depending on the 4386 4401 ** current datatype. */ 4387 4402 u16 origFlags = pIn3->flags; 4388 4403 int isNotInt; 4389 4404 applyAffinity(pIn3, SQLITE_AFF_NUMERIC, encoding);
Changes to src/vdbeapi.c.
230 230 #endif /* SQLITE_OMIT_UTF16 */ 231 231 /* EVIDENCE-OF: R-12793-43283 Every value in SQLite has one of five 232 232 ** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating 233 233 ** point number string BLOB NULL 234 234 */ 235 235 int sqlite3_value_type(sqlite3_value* pVal){ 236 236 static const u8 aType[] = { 237 - SQLITE_BLOB, /* 0x00 */ 238 - SQLITE_NULL, /* 0x01 */ 239 - SQLITE_TEXT, /* 0x02 */ 240 - SQLITE_NULL, /* 0x03 */ 241 - SQLITE_INTEGER, /* 0x04 */ 242 - SQLITE_NULL, /* 0x05 */ 243 - SQLITE_INTEGER, /* 0x06 */ 244 - SQLITE_NULL, /* 0x07 */ 245 - SQLITE_FLOAT, /* 0x08 */ 246 - SQLITE_NULL, /* 0x09 */ 247 - SQLITE_FLOAT, /* 0x0a */ 248 - SQLITE_NULL, /* 0x0b */ 249 - SQLITE_INTEGER, /* 0x0c */ 250 - SQLITE_NULL, /* 0x0d */ 251 - SQLITE_INTEGER, /* 0x0e */ 252 - SQLITE_NULL, /* 0x0f */ 253 - SQLITE_BLOB, /* 0x10 */ 254 - SQLITE_NULL, /* 0x11 */ 255 - SQLITE_TEXT, /* 0x12 */ 256 - SQLITE_NULL, /* 0x13 */ 257 - SQLITE_INTEGER, /* 0x14 */ 258 - SQLITE_NULL, /* 0x15 */ 259 - SQLITE_INTEGER, /* 0x16 */ 260 - SQLITE_NULL, /* 0x17 */ 261 - SQLITE_FLOAT, /* 0x18 */ 262 - SQLITE_NULL, /* 0x19 */ 263 - SQLITE_FLOAT, /* 0x1a */ 264 - SQLITE_NULL, /* 0x1b */ 265 - SQLITE_INTEGER, /* 0x1c */ 266 - SQLITE_NULL, /* 0x1d */ 267 - SQLITE_INTEGER, /* 0x1e */ 268 - SQLITE_NULL, /* 0x1f */ 269 - SQLITE_BLOB, /* 0x20 */ 270 - SQLITE_NULL, /* 0x21 */ 271 - SQLITE_TEXT, /* 0x22 */ 272 - SQLITE_NULL, /* 0x23 */ 273 - SQLITE_FLOAT, /* 0x24 */ 274 - SQLITE_NULL, /* 0x25 */ 275 - SQLITE_FLOAT, /* 0x26 */ 276 - SQLITE_NULL, /* 0x27 */ 277 - SQLITE_FLOAT, /* 0x28 */ 278 - SQLITE_NULL, /* 0x29 */ 279 - SQLITE_FLOAT, /* 0x2a */ 280 - SQLITE_NULL, /* 0x2b */ 281 - SQLITE_FLOAT, /* 0x2c */ 282 - SQLITE_NULL, /* 0x2d */ 283 - SQLITE_FLOAT, /* 0x2e */ 284 - SQLITE_NULL, /* 0x2f */ 285 - SQLITE_BLOB, /* 0x30 */ 286 - SQLITE_NULL, /* 0x31 */ 287 - SQLITE_TEXT, /* 0x32 */ 288 - SQLITE_NULL, /* 0x33 */ 289 - SQLITE_FLOAT, /* 0x34 */ 290 - SQLITE_NULL, /* 0x35 */ 291 - SQLITE_FLOAT, /* 0x36 */ 292 - SQLITE_NULL, /* 0x37 */ 293 - SQLITE_FLOAT, /* 0x38 */ 294 - SQLITE_NULL, /* 0x39 */ 295 - SQLITE_FLOAT, /* 0x3a */ 296 - SQLITE_NULL, /* 0x3b */ 297 - SQLITE_FLOAT, /* 0x3c */ 298 - SQLITE_NULL, /* 0x3d */ 299 - SQLITE_FLOAT, /* 0x3e */ 300 - SQLITE_NULL, /* 0x3f */ 237 + SQLITE_BLOB, /* 0x00 (not possible) */ 238 + SQLITE_NULL, /* 0x01 NULL */ 239 + SQLITE_TEXT, /* 0x02 TEXT */ 240 + SQLITE_NULL, /* 0x03 (not possible) */ 241 + SQLITE_INTEGER, /* 0x04 INTEGER */ 242 + SQLITE_NULL, /* 0x05 (not possible) */ 243 + SQLITE_INTEGER, /* 0x06 INTEGER + TEXT */ 244 + SQLITE_NULL, /* 0x07 (not possible) */ 245 + SQLITE_FLOAT, /* 0x08 FLOAT */ 246 + SQLITE_NULL, /* 0x09 (not possible) */ 247 + SQLITE_FLOAT, /* 0x0a FLOAT + TEXT */ 248 + SQLITE_NULL, /* 0x0b (not possible) */ 249 + SQLITE_INTEGER, /* 0x0c (not possible) */ 250 + SQLITE_NULL, /* 0x0d (not possible) */ 251 + SQLITE_INTEGER, /* 0x0e (not possible) */ 252 + SQLITE_NULL, /* 0x0f (not possible) */ 253 + SQLITE_BLOB, /* 0x10 BLOB */ 254 + SQLITE_NULL, /* 0x11 (not possible) */ 255 + SQLITE_TEXT, /* 0x12 (not possible) */ 256 + SQLITE_NULL, /* 0x13 (not possible) */ 257 + SQLITE_INTEGER, /* 0x14 INTEGER + BLOB */ 258 + SQLITE_NULL, /* 0x15 (not possible) */ 259 + SQLITE_INTEGER, /* 0x16 (not possible) */ 260 + SQLITE_NULL, /* 0x17 (not possible) */ 261 + SQLITE_FLOAT, /* 0x18 FLOAT + BLOB */ 262 + SQLITE_NULL, /* 0x19 (not possible) */ 263 + SQLITE_FLOAT, /* 0x1a (not possible) */ 264 + SQLITE_NULL, /* 0x1b (not possible) */ 265 + SQLITE_INTEGER, /* 0x1c (not possible) */ 266 + SQLITE_NULL, /* 0x1d (not possible) */ 267 + SQLITE_INTEGER, /* 0x1e (not possible) */ 268 + SQLITE_NULL, /* 0x1f (not possible) */ 269 + SQLITE_FLOAT, /* 0x20 INTREAL */ 270 + SQLITE_NULL, /* 0x21 (not possible) */ 271 + SQLITE_TEXT, /* 0x22 INTREAL + TEXT */ 272 + SQLITE_NULL, /* 0x23 (not possible) */ 273 + SQLITE_FLOAT, /* 0x24 (not possible) */ 274 + SQLITE_NULL, /* 0x25 (not possible) */ 275 + SQLITE_FLOAT, /* 0x26 (not possible) */ 276 + SQLITE_NULL, /* 0x27 (not possible) */ 277 + SQLITE_FLOAT, /* 0x28 (not possible) */ 278 + SQLITE_NULL, /* 0x29 (not possible) */ 279 + SQLITE_FLOAT, /* 0x2a (not possible) */ 280 + SQLITE_NULL, /* 0x2b (not possible) */ 281 + SQLITE_FLOAT, /* 0x2c (not possible) */ 282 + SQLITE_NULL, /* 0x2d (not possible) */ 283 + SQLITE_FLOAT, /* 0x2e (not possible) */ 284 + SQLITE_NULL, /* 0x2f (not possible) */ 285 + SQLITE_BLOB, /* 0x30 (not possible) */ 286 + SQLITE_NULL, /* 0x31 (not possible) */ 287 + SQLITE_TEXT, /* 0x32 (not possible) */ 288 + SQLITE_NULL, /* 0x33 (not possible) */ 289 + SQLITE_FLOAT, /* 0x34 (not possible) */ 290 + SQLITE_NULL, /* 0x35 (not possible) */ 291 + SQLITE_FLOAT, /* 0x36 (not possible) */ 292 + SQLITE_NULL, /* 0x37 (not possible) */ 293 + SQLITE_FLOAT, /* 0x38 (not possible) */ 294 + SQLITE_NULL, /* 0x39 (not possible) */ 295 + SQLITE_FLOAT, /* 0x3a (not possible) */ 296 + SQLITE_NULL, /* 0x3b (not possible) */ 297 + SQLITE_FLOAT, /* 0x3c (not possible) */ 298 + SQLITE_NULL, /* 0x3d (not possible) */ 299 + SQLITE_FLOAT, /* 0x3e (not possible) */ 300 + SQLITE_NULL, /* 0x3f (not possible) */ 301 301 }; 302 302 #ifdef SQLITE_DEBUG 303 303 { 304 304 int eType = SQLITE_BLOB; 305 305 if( pVal->flags & MEM_Null ){ 306 306 eType = SQLITE_NULL; 307 - }else if( pVal->flags & MEM_Int ){ 308 - eType = (pVal->flags & MEM_IntReal) ? SQLITE_FLOAT : SQLITE_INTEGER; 309 - }else if( pVal->flags & MEM_Real ){ 307 + }else if( pVal->flags & (MEM_Real|MEM_IntReal) ){ 310 308 eType = SQLITE_FLOAT; 309 + }else if( pVal->flags & MEM_Int ){ 310 + eType = SQLITE_INTEGER; 311 311 }else if( pVal->flags & MEM_Str ){ 312 312 eType = SQLITE_TEXT; 313 313 } 314 314 assert( eType == aType[pVal->flags&MEM_AffMask] ); 315 315 } 316 316 #endif 317 317 return aType[pVal->flags&MEM_AffMask]; ................................................................................ 558 558 /* An SQLITE_NOMEM error. */ 559 559 void sqlite3_result_error_nomem(sqlite3_context *pCtx){ 560 560 assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); 561 561 sqlite3VdbeMemSetNull(pCtx->pOut); 562 562 pCtx->isError = SQLITE_NOMEM_BKPT; 563 563 sqlite3OomFault(pCtx->pOut->db); 564 564 } 565 + 566 +#ifndef SQLITE_UNTESTABLE 567 +/* Force the INT64 value currently stored as the result to be 568 +** a MEM_IntReal value. See the SQLITE_TESTCTRL_RESULT_INTREAL 569 +** test-control. 570 +*/ 571 +void sqlite3ResultIntReal(sqlite3_context *pCtx){ 572 + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); 573 + if( pCtx->pOut->flags & MEM_Int ){ 574 + pCtx->pOut->flags &= ~MEM_Int; 575 + pCtx->pOut->flags |= MEM_IntReal; 576 + } 577 +} 578 +#endif 579 + 565 580 566 581 /* 567 582 ** This function is called after a transaction has been committed. It 568 583 ** invokes callbacks registered with sqlite3_wal_hook() as required. 569 584 */ 570 585 static int doWalCallbacks(sqlite3 *db){ 571 586 int rc = SQLITE_OK; ................................................................................ 1845 1860 1846 1861 pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; 1847 1862 if( iIdx==p->pTab->iPKey ){ 1848 1863 sqlite3VdbeMemSetInt64(pMem, p->iKey1); 1849 1864 }else if( iIdx>=p->pUnpacked->nField ){ 1850 1865 *ppValue = (sqlite3_value *)columnNullValue(); 1851 1866 }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ 1852 - if( pMem->flags & MEM_Int ){ 1867 + if( pMem->flags & (MEM_Int|MEM_IntReal) ){ 1868 + testcase( pMem->flags & MEM_Int ); 1869 + testcase( pMem->flags & MEM_IntReal ); 1853 1870 sqlite3VdbeMemRealify(pMem); 1854 1871 } 1855 1872 } 1856 1873 1857 1874 preupdate_old_out: 1858 1875 sqlite3Error(db, rc); 1859 1876 return sqlite3ApiExit(db, rc);
Changes to src/vdbeaux.c.
1530 1530 sqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal); 1531 1531 break; 1532 1532 } 1533 1533 case P4_MEM: { 1534 1534 Mem *pMem = pOp->p4.pMem; 1535 1535 if( pMem->flags & MEM_Str ){ 1536 1536 zP4 = pMem->z; 1537 - }else if( pMem->flags & MEM_Int ){ 1537 + }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){ 1538 1538 sqlite3_str_appendf(&x, "%lld", pMem->u.i); 1539 1539 }else if( pMem->flags & MEM_Real ){ 1540 1540 sqlite3_str_appendf(&x, "%.16g", pMem->u.r); 1541 1541 }else if( pMem->flags & MEM_Null ){ 1542 1542 zP4 = "NULL"; 1543 1543 }else{ 1544 1544 assert( pMem->flags & MEM_Blob ); ................................................................................ 3428 3428 u32 n; 3429 3429 3430 3430 assert( pLen!=0 ); 3431 3431 if( flags&MEM_Null ){ 3432 3432 *pLen = 0; 3433 3433 return 0; 3434 3434 } 3435 - if( flags&MEM_Int ){ 3435 + if( flags&(MEM_Int|MEM_IntReal) ){ 3436 3436 /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */ 3437 3437 # define MAX_6BYTE ((((i64)0x00008000)<<32)-1) 3438 3438 i64 i = pMem->u.i; 3439 3439 u64 u; 3440 + testcase( flags & MEM_Int ); 3441 + testcase( flags & MEM_IntReal ); 3440 3442 if( i<0 ){ 3441 3443 u = ~i; 3442 3444 }else{ 3443 3445 u = i; 3444 3446 } 3445 3447 if( u<=127 ){ 3446 3448 if( (i&1)==i && file_format>=4 ){ ................................................................................ 4107 4109 */ 4108 4110 if( combined_flags&MEM_Null ){ 4109 4111 return (f2&MEM_Null) - (f1&MEM_Null); 4110 4112 } 4111 4113 4112 4114 /* At least one of the two values is a number 4113 4115 */ 4114 - if( combined_flags&(MEM_Int|MEM_Real) ){ 4115 - if( (f1 & f2 & MEM_Int)!=0 ){ 4116 + if( combined_flags&(MEM_Int|MEM_Real|MEM_IntReal) ){ 4117 + testcase( combined_flags & MEM_Int ); 4118 + testcase( combined_flags & MEM_Real ); 4119 + testcase( combined_flags & MEM_IntReal ); 4120 + if( (f1 & f2 & (MEM_Int|MEM_IntReal))!=0 ){ 4121 + testcase( f1 & f2 & MEM_Int ); 4122 + testcase( f1 & f2 & MEM_IntReal ); 4116 4123 if( pMem1->u.i < pMem2->u.i ) return -1; 4117 4124 if( pMem1->u.i > pMem2->u.i ) return +1; 4118 4125 return 0; 4119 4126 } 4120 4127 if( (f1 & f2 & MEM_Real)!=0 ){ 4121 4128 if( pMem1->u.r < pMem2->u.r ) return -1; 4122 4129 if( pMem1->u.r > pMem2->u.r ) return +1; 4123 4130 return 0; 4124 4131 } 4125 - if( (f1&MEM_Int)!=0 ){ 4132 + if( (f1&(MEM_Int|MEM_IntReal))!=0 ){ 4133 + testcase( f1 & MEM_Int ); 4134 + testcase( f1 & MEM_IntReal ); 4126 4135 if( (f2&MEM_Real)!=0 ){ 4127 4136 return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r); 4137 + }else if( (f2&(MEM_Int|MEM_IntReal))!=0 ){ 4138 + if( pMem1->u.i < pMem2->u.i ) return -1; 4139 + if( pMem1->u.i > pMem2->u.i ) return +1; 4140 + return 0; 4128 4141 }else{ 4129 4142 return -1; 4130 4143 } 4131 4144 } 4132 4145 if( (f1&MEM_Real)!=0 ){ 4133 - if( (f2&MEM_Int)!=0 ){ 4146 + if( (f2&(MEM_Int|MEM_IntReal))!=0 ){ 4147 + testcase( f2 & MEM_Int ); 4148 + testcase( f2 & MEM_IntReal ); 4134 4149 return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r); 4135 4150 }else{ 4136 4151 return -1; 4137 4152 } 4138 4153 } 4139 4154 return +1; 4140 4155 } ................................................................................ 4275 4290 assert( pPKey2->pKeyInfo->aSortOrder!=0 ); 4276 4291 assert( pPKey2->pKeyInfo->nKeyField>0 ); 4277 4292 assert( idx1<=szHdr1 || CORRUPT_DB ); 4278 4293 do{ 4279 4294 u32 serial_type; 4280 4295 4281 4296 /* RHS is an integer */ 4282 - if( pRhs->flags & MEM_Int ){ 4297 + if( pRhs->flags & (MEM_Int|MEM_IntReal) ){ 4298 + testcase( pRhs->flags & MEM_Int ); 4299 + testcase( pRhs->flags & MEM_IntReal ); 4283 4300 serial_type = aKey1[idx1]; 4284 4301 testcase( serial_type==12 ); 4285 4302 if( serial_type>=10 ){ 4286 4303 rc = +1; 4287 4304 }else if( serial_type==0 ){ 4288 4305 rc = -1; 4289 4306 }else if( serial_type==7 ){ ................................................................................ 4620 4637 } 4621 4638 if( (flags & MEM_Int) ){ 4622 4639 return vdbeRecordCompareInt; 4623 4640 } 4624 4641 testcase( flags & MEM_Real ); 4625 4642 testcase( flags & MEM_Null ); 4626 4643 testcase( flags & MEM_Blob ); 4627 - if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){ 4644 + if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0 4645 + && p->pKeyInfo->aColl[0]==0 4646 + ){ 4628 4647 assert( flags & MEM_Str ); 4629 4648 return vdbeRecordCompareString; 4630 4649 } 4631 4650 } 4632 4651 4633 4652 return sqlite3VdbeRecordCompare; 4634 4653 }
Changes to src/vdbemem.c.
14 14 ** stores a single value in the VDBE. Mem is an opaque structure visible 15 15 ** only within the VDBE. Interface routines refer to a Mem using the 16 16 ** name sqlite_value 17 17 */ 18 18 #include "sqliteInt.h" 19 19 #include "vdbeInt.h" 20 20 21 +/* True if X is a power of two. 0 is considered a power of two here. 22 +** In other words, return true if X has at most one bit set. 23 +*/ 24 +#define ISPOWEROF2(X) (((X)&((X)-1))==0) 25 + 21 26 #ifdef SQLITE_DEBUG 22 27 /* 23 28 ** Check invariants on a Mem object. 24 29 ** 25 30 ** This routine is intended for use inside of assert() statements, like 26 31 ** this: assert( sqlite3VdbeCheckMemInvariants(pMem) ); 27 32 */ ................................................................................ 33 38 34 39 /* MEM_Dyn may only be set if Mem.szMalloc==0. In this way we 35 40 ** ensure that if Mem.szMalloc>0 then it is safe to do 36 41 ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn. 37 42 ** That saves a few cycles in inner loops. */ 38 43 assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 ); 39 44 40 - /* Cannot be both MEM_Int and MEM_Real at the same time */ 41 - assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) ); 45 + /* Cannot have more than one of MEM_Int, MEM_Real, or MEM_IntReal */ 46 + assert( ISPOWEROF2(p->flags & (MEM_Int|MEM_Real|MEM_IntReal)) ); 42 47 43 48 if( p->flags & MEM_Null ){ 44 49 /* Cannot be both MEM_Null and some other type */ 45 50 assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 ); 46 51 47 52 /* If MEM_Null is set, then either the value is a pure NULL (the usual 48 53 ** case) or it is a pointer set using sqlite3_bind_pointer() or ................................................................................ 89 94 ); 90 95 } 91 96 return 1; 92 97 } 93 98 #endif 94 99 95 100 /* 96 -** Render a Mem object which is either MEM_Int or MEM_Real into a 97 -** buffer. 101 +** Render a Mem object which is one of MEM_Int, MEM_Real, or MEM_IntReal 102 +** into a buffer. 98 103 */ 99 104 static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){ 100 105 StrAccum acc; 101 - assert( p->flags & (MEM_Int|MEM_Real) ); 106 + assert( p->flags & (MEM_Int|MEM_Real|MEM_IntReal) ); 102 107 sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0); 103 - if( p->flags & MEM_IntReal ){ 104 - sqlite3_str_appendf(&acc, "%!.15g", (double)p->u.i); 105 - }else if( p->flags & MEM_Int ){ 108 + if( p->flags & MEM_Int ){ 106 109 sqlite3_str_appendf(&acc, "%lld", p->u.i); 110 + }else if( p->flags & MEM_IntReal ){ 111 + sqlite3_str_appendf(&acc, "%!.15g", (double)p->u.i); 107 112 }else{ 108 113 sqlite3_str_appendf(&acc, "%!.15g", p->u.r); 109 114 } 110 115 assert( acc.zText==zBuf && acc.mxAlloc<=0 ); 111 116 zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */ 112 117 } 113 118 ................................................................................ 132 137 ** This routine is for use inside of assert() statements only. 133 138 */ 134 139 int sqlite3VdbeMemConsistentDualRep(Mem *p){ 135 140 char zBuf[100]; 136 141 char *z; 137 142 int i, j, incr; 138 143 if( (p->flags & MEM_Str)==0 ) return 1; 139 - if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1; 144 + if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1; 140 145 vdbeMemRenderNum(sizeof(zBuf), zBuf, p); 141 146 z = p->z; 142 147 i = j = 0; 143 148 incr = 1; 144 149 if( p->enc!=SQLITE_UTF8 ){ 145 150 incr = 2; 146 151 if( p->enc==SQLITE_UTF16BE ) z++; ................................................................................ 245 250 /* 246 251 ** Change the pMem->zMalloc allocation to be at least szNew bytes. 247 252 ** If pMem->zMalloc already meets or exceeds the requested size, this 248 253 ** routine is a no-op. 249 254 ** 250 255 ** Any prior string or blob content in the pMem object may be discarded. 251 256 ** The pMem->xDel destructor is called, if it exists. Though MEM_Str 252 -** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, and MEM_Null 253 -** values are preserved. 257 +** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, MEM_IntReal, 258 +** and MEM_Null values are preserved. 254 259 ** 255 260 ** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM) 256 261 ** if unable to complete the resizing. 257 262 */ 258 263 int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ 259 264 assert( CORRUPT_DB || szNew>0 ); 260 265 assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 ); ................................................................................ 350 355 } 351 356 352 357 /* 353 358 ** Add MEM_Str to the set of representations for the given Mem. Numbers 354 359 ** are converted using sqlite3_snprintf(). Converting a BLOB to a string 355 360 ** is a no-op. 356 361 ** 357 -** Existing representations MEM_Int and MEM_Real are invalidated if 358 -** bForce is true but are retained if bForce is false. 362 +** Existing representations MEM_Int, MEM_Real, or MEM_IntReal are invalidated 363 +** if bForce is true but are retained if bForce is false. 359 364 ** 360 365 ** A MEM_Null value will never be passed to this function. This function is 361 366 ** used for converting values to text for returning to the user (i.e. via 362 367 ** sqlite3_value_text()), or for ensuring that values to be used as btree 363 368 ** keys are strings. In the former case a NULL pointer is returned the 364 369 ** user and the latter is an internal programming error. 365 370 */ 366 371 int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ 367 372 const int nByte = 32; 368 373 369 374 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); 370 375 assert( !(pMem->flags&MEM_Zero) ); 371 376 assert( !(pMem->flags&(MEM_Str|MEM_Blob)) ); 372 - assert( pMem->flags&(MEM_Int|MEM_Real) ); 377 + assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) ); 373 378 assert( !sqlite3VdbeMemIsRowSet(pMem) ); 374 379 assert( EIGHT_BYTE_ALIGNMENT(pMem) ); 375 380 376 381 377 382 if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){ 378 383 pMem->enc = 0; 379 384 return SQLITE_NOMEM_BKPT; ................................................................................ 554 559 return value; 555 560 } 556 561 i64 sqlite3VdbeIntValue(Mem *pMem){ 557 562 int flags; 558 563 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); 559 564 assert( EIGHT_BYTE_ALIGNMENT(pMem) ); 560 565 flags = pMem->flags; 561 - if( flags & MEM_Int ){ 566 + if( flags & (MEM_Int|MEM_IntReal) ){ 567 + testcase( flags & MEM_IntReal ); 562 568 return pMem->u.i; 563 569 }else if( flags & MEM_Real ){ 564 570 return doubleToInt64(pMem->u.r); 565 571 }else if( flags & (MEM_Str|MEM_Blob) ){ 566 572 assert( pMem->z || pMem->n==0 ); 567 573 return memIntValue(pMem); 568 574 }else{ ................................................................................ 583 589 return val; 584 590 } 585 591 double sqlite3VdbeRealValue(Mem *pMem){ 586 592 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); 587 593 assert( EIGHT_BYTE_ALIGNMENT(pMem) ); 588 594 if( pMem->flags & MEM_Real ){ 589 595 return pMem->u.r; 590 - }else if( pMem->flags & MEM_Int ){ 596 + }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){ 597 + testcase( pMem->flags & MEM_IntReal ); 591 598 return (double)pMem->u.i; 592 599 }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ 593 600 return memRealValue(pMem); 594 601 }else{ 595 602 /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ 596 603 return (double)0; 597 604 } ................................................................................ 598 605 } 599 606 600 607 /* 601 608 ** Return 1 if pMem represents true, and return 0 if pMem represents false. 602 609 ** Return the value ifNull if pMem is NULL. 603 610 */ 604 611 int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){ 605 - if( pMem->flags & MEM_Int ) return pMem->u.i!=0; 612 + testcase( pMem->flags & MEM_IntReal ); 613 + if( pMem->flags & (MEM_Int|MEM_IntReal) ) return pMem->u.i!=0; 606 614 if( pMem->flags & MEM_Null ) return ifNull; 607 615 return sqlite3VdbeRealValue(pMem)!=0.0; 608 616 } 609 617 610 618 /* 611 619 ** The MEM structure is already a MEM_Real. Try to also make it a 612 620 ** MEM_Int if we can. ................................................................................ 671 679 */ 672 680 static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){ 673 681 double r2 = (double)i; 674 682 return memcmp(&r1, &r2, sizeof(r1))==0; 675 683 } 676 684 677 685 /* 678 -** Convert pMem so that it has types MEM_Real or MEM_Int or both. 686 +** Convert pMem so that it has type MEM_Real or MEM_Int. 679 687 ** Invalidate any prior representations. 680 688 ** 681 689 ** Every effort is made to force the conversion, even if the input 682 690 ** is a string that does not look completely like a number. Convert 683 691 ** as much of the string as we can and ignore the rest. 684 692 */ 685 693 int sqlite3VdbeMemNumerify(Mem *pMem){ 686 - if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){ 694 + testcase( pMem->flags & MEM_Int ); 695 + testcase( pMem->flags & MEM_Real ); 696 + testcase( pMem->flags & MEM_IntReal ); 697 + testcase( pMem->flags & MEM_Null ); 698 + if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){ 687 699 int rc; 688 700 assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); 689 701 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); 690 702 rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc); 691 703 if( rc==0 ){ 692 704 MemSetTypeFlag(pMem, MEM_Int); 693 705 }else{ ................................................................................ 697 709 pMem->u.i = i; 698 710 MemSetTypeFlag(pMem, MEM_Int); 699 711 }else{ 700 712 MemSetTypeFlag(pMem, MEM_Real); 701 713 } 702 714 } 703 715 } 704 - assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 ); 716 + assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))!=0 ); 705 717 pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero); 706 718 return SQLITE_OK; 707 719 } 708 720 709 721 /* 710 722 ** Cast the datatype of the value in pMem according to the affinity 711 723 ** "aff". Casting is different from applying affinity in that a cast ................................................................................ 924 936 /* If pX is marked as a shallow copy of pMem, then verify that 925 937 ** no significant changes have been made to pX since the OP_SCopy. 926 938 ** A significant change would indicated a missed call to this 927 939 ** function for pX. Minor changes, such as adding or removing a 928 940 ** dual type, are allowed, as long as the underlying value is the 929 941 ** same. */ 930 942 u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags; 931 - assert( (mFlags&MEM_Int)==0 || pMem->u.i==pX->u.i ); 943 + assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i ); 932 944 assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r ); 933 945 assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) ); 934 946 assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 ); 935 947 936 948 /* pMem is the register that is changing. But also mark pX as 937 949 ** undefined so that we can quickly detect the shallow-copy error */ 938 950 pX->flags = MEM_Undefined; ................................................................................ 1487 1499 sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); 1488 1500 } 1489 1501 if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_BLOB ){ 1490 1502 sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); 1491 1503 }else{ 1492 1504 sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); 1493 1505 } 1494 - if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str; 1506 + assert( (pVal->flags & MEM_IntReal)==0 ); 1507 + if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ){ 1508 + testcase( pVal->flags & MEM_Int ); 1509 + testcase( pVal->flags & MEM_Real ); 1510 + pVal->flags &= ~MEM_Str; 1511 + } 1495 1512 if( enc!=SQLITE_UTF8 ){ 1496 1513 rc = sqlite3VdbeChangeEncoding(pVal, enc); 1497 1514 } 1498 1515 }else if( op==TK_UMINUS ) { 1499 1516 /* This branch happens for multiple negative signs. Ex: -(-5) */ 1500 1517 if( SQLITE_OK==valueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal,pCtx) 1501 1518 && pVal!=0
Changes to src/vdbetrace.c.
126 126 } 127 127 zRawSql += nToken; 128 128 nextIndex = idx + 1; 129 129 assert( idx>0 && idx<=p->nVar ); 130 130 pVar = &p->aVar[idx-1]; 131 131 if( pVar->flags & MEM_Null ){ 132 132 sqlite3_str_append(&out, "NULL", 4); 133 - }else if( pVar->flags & MEM_Int ){ 133 + }else if( pVar->flags & (MEM_Int|MEM_IntReal) ){ 134 134 sqlite3_str_appendf(&out, "%lld", pVar->u.i); 135 135 }else if( pVar->flags & MEM_Real ){ 136 136 sqlite3_str_appendf(&out, "%!.15g", pVar->u.r); 137 137 }else if( pVar->flags & MEM_Str ){ 138 138 int nOut; /* Number of bytes of the string text to include in output */ 139 139 #ifndef SQLITE_OMIT_UTF16 140 140 u8 enc = ENC(db);
Added test/intreal.test.
1 +# 2019-05-03 2 +# 3 +# The author disclaims copyright to this source code. In place of 4 +# a legal notice, here is a blessing: 5 +# 6 +# May you do good and not evil. 7 +# May you find forgiveness for yourself and forgive others. 8 +# May you share freely, never taking more than you give. 9 +# 10 +#*********************************************************************** 11 +# Tests to exercise the MEM_IntReal representation of Mem objects. 12 +# 13 +set testdir [file dirname $argv0] 14 +source $testdir/tester.tcl 15 +set ::testprefix intreal 16 + 17 +sqlite3_create_function db 18 +do_execsql_test 100 { 19 + SELECT intreal(5); 20 +} {5.0} 21 +do_execsql_test 110 { 22 + SELECT intreal(5)=5, 6=intreal(6); 23 +} {1 1} 24 +do_execsql_test 120 { 25 + SELECT intreal(7)=7.0, 8.0=intreal(8); 26 +} {1 1} 27 +do_execsql_test 130 { 28 + SELECT typeof(intreal(9)); 29 +} {real} 30 +do_execsql_test 140 { 31 + SELECT 'a'||intreal(11)||'z'; 32 +} {a11.0z} 33 + 34 +do_execsql_test 150 { 35 + SELECT max(1.0,intreal(2),3.0), max(1,intreal(2),3); 36 +} {3.0 3} 37 +do_execsql_test 160 { 38 + SELECT max(1.0,intreal(4),3.0), max(1,intreal(4),3); 39 +} {4.0 4.0} 40 +do_execsql_test 170 { 41 + SELECT max(1.0,intreal(2),intreal(3),4.0), 42 + max(1,intreal(2),intreal(3),4); 43 +} {4.0 4} 44 +do_execsql_test 180 { 45 + SELECT max(1.0,intreal(5),intreal(3),4.0), 46 + max(1,intreal(5),intreal(3),4); 47 +} {5.0 5.0} 48 + 49 + 50 + 51 + 52 +finish_test