Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | When casting string values into numeric and the string has a prefix that looks like a number but total string is not a well-formed number, then take extra care that the result is either integer or real depending on what the prefix looks like. Fix for tickets [e8bedb2a184001] and [4c2d7639f076aa]. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
67a68af5578f08d2be2e48cf4fd12a6c |
User & Date: | drh 2019-06-07 22:26:08 |
References
2019-06-08
| ||
21:31 | • New ticket [dd6bffbf] CAST to NUMERIC no longer converts to INTEGER. (artifact: f550c0f0 user: mrigger) | |
Context
2019-06-07
| ||
22:51 | Remove code in the round() SQL function that became unreachable due to the optimization of check-in [e95138f5f4febde5] (check-in: b141bae3 user: drh tags: trunk) | |
22:26 | When casting string values into numeric and the string has a prefix that looks like a number but total string is not a well-formed number, then take extra care that the result is either integer or real depending on what the prefix looks like. Fix for tickets [e8bedb2a184001] and [4c2d7639f076aa]. (check-in: 67a68af5 user: drh tags: trunk) | |
18:56 | Also upgrade script config.sub to the latest version. This should have been part of the previous commit. (check-in: efbf31b8 user: dan tags: trunk) | |
Changes
Changes to src/date.c.
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 ... 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 ... 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 |
double r; if( parseYyyyMmDd(zDate,p)==0 ){ return 0; }else if( parseHhMmSs(zDate, p)==0 ){ return 0; }else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){ return setDateTimeToCurrent(context, p); }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){ setRawDateNumber(p, r); return 0; } return 1; } /* The julian day number for 9999-12-31 23:59:59.999 is 5373484.4999999. ................................................................................ ** weekday N ** ** Move the date to the same time on the next occurrence of ** weekday N where 0==Sunday, 1==Monday, and so forth. If the ** date is already on the appropriate weekday, this is a no-op. */ if( sqlite3_strnicmp(z, "weekday ", 8)==0 && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8) && (n=(int)r)==r && n>=0 && r<7 ){ sqlite3_int64 Z; computeYMD_HMS(p); p->validTZ = 0; p->validJD = 0; computeJD(p); Z = ((p->iJD + 129600000)/86400000) % 7; ................................................................................ case '6': case '7': case '8': case '9': { double rRounder; int i; for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){ rc = 1; break; } if( z[n]==':' ){ /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the ** specified number of hours, minutes, seconds, and fractional seconds ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be |
| | | |
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 ... 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 ... 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 |
double r; if( parseYyyyMmDd(zDate,p)==0 ){ return 0; }else if( parseHhMmSs(zDate, p)==0 ){ return 0; }else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){ return setDateTimeToCurrent(context, p); }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){ setRawDateNumber(p, r); return 0; } return 1; } /* The julian day number for 9999-12-31 23:59:59.999 is 5373484.4999999. ................................................................................ ** weekday N ** ** Move the date to the same time on the next occurrence of ** weekday N where 0==Sunday, 1==Monday, and so forth. If the ** date is already on the appropriate weekday, this is a no-op. */ if( sqlite3_strnicmp(z, "weekday ", 8)==0 && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0 && (n=(int)r)==r && n>=0 && r<7 ){ sqlite3_int64 Z; computeYMD_HMS(p); p->validTZ = 0; p->validJD = 0; computeJD(p); Z = ((p->iJD + 129600000)/86400000) % 7; ................................................................................ case '6': case '7': case '8': case '9': { double rRounder; int i; for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){ rc = 1; break; } if( z[n]==':' ){ /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the ** specified number of hours, minutes, seconds, and fractional seconds ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be |
Changes to src/func.c.
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5)));
}else{
zBuf = sqlite3_mprintf("%.*f",n,r);
if( zBuf==0 ){
sqlite3_result_error_nomem(context);
return;
}
if( !sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8) ){
assert( sqlite3_strglob("*Inf", zBuf)==0 );
r = zBuf[0]=='-' ? -HUGE_VAL : +HUGE_VAL;
}
sqlite3_free(zBuf);
}
sqlite3_result_double(context, r);
}
|
| |
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5)));
}else{
zBuf = sqlite3_mprintf("%.*f",n,r);
if( zBuf==0 ){
sqlite3_result_error_nomem(context);
return;
}
if( sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8)<=0 ){
assert( sqlite3_strglob("*Inf", zBuf)==0 );
r = zBuf[0]=='-' ? -HUGE_VAL : +HUGE_VAL;
}
sqlite3_free(zBuf);
}
sqlite3_result_double(context, r);
}
|
Changes to src/util.c.
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 ... 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 ... 595 596 597 598 599 600 601 602 603 604 605 606 607 608 ... 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 |
** uses the encoding enc. The string is not necessarily zero-terminated. ** ** Return TRUE if the result is a valid real number (or integer) and FALSE ** if the string is empty or contains extraneous text. More specifically ** return ** 1 => The input string is a pure integer ** 2 or more => The input has a decimal point or eNNN clause ** 0 => The input string is not a valid number ** ** Valid numbers are in one of these formats: ** ** [+-]digits[E[+-]digits] ** [+-]digits.[digits][E[+-]digits] ** [+-].digits[E[+-]digits] ** ................................................................................ } } /* store the result */ *pResult = result; /* return true if number and no extra non-whitespace chracters after */ return z==zEnd && nDigit>0 && eValid && eType>0 ? eType : 0; #else return !sqlite3Atoi64(z, pResult, length, enc); #endif /* SQLITE_OMIT_FLOATING_POINT */ } /* ** Compare the 19-character string zNum against the text representation ................................................................................ /* ** Convert zNum to a 64-bit signed integer. zNum must be decimal. This ** routine does *not* accept hexadecimal notation. ** ** Returns: ** ** 0 Successful transformation. Fits in a 64-bit signed integer. ** 1 Excess non-space text after the integer value ** 2 Integer too large for a 64-bit signed integer or is malformed ** 3 Special case of 9223372036854775808 ** ** length is the number of bytes in the string (bytes, not characters). ** The string is not necessarily zero-terminated. The encoding is ................................................................................ *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; }else if( neg ){ *pNum = -(i64)u; }else{ *pNum = (i64)u; } rc = 0; if( (i==0 && zStart==zNum) /* No digits */ || nonNum /* UTF16 with high-order bytes non-zero */ ){ rc = 1; }else if( &zNum[i]<zEnd ){ /* Extra bytes at the end */ int jj = i; do{ if( !sqlite3Isspace(zNum[jj]) ){ rc = 1; /* Extra non-space text after the integer */ break; |
| > > | > > > > > > > | | | |
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 ... 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 ... 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 ... 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 |
** uses the encoding enc. The string is not necessarily zero-terminated. ** ** Return TRUE if the result is a valid real number (or integer) and FALSE ** if the string is empty or contains extraneous text. More specifically ** return ** 1 => The input string is a pure integer ** 2 or more => The input has a decimal point or eNNN clause ** 0 or less => The input string is not a valid number ** -1 => Not a valid number, but has a valid prefix which ** includes a decimal point and/or an eNNN clause ** ** Valid numbers are in one of these formats: ** ** [+-]digits[E[+-]digits] ** [+-]digits.[digits][E[+-]digits] ** [+-].digits[E[+-]digits] ** ................................................................................ } } /* store the result */ *pResult = result; /* return true if number and no extra non-whitespace chracters after */ if( z==zEnd && nDigit>0 && eValid && eType>0 ){ return eType; }else if( eType>=2 && (eType==3 || eValid) ){ return -1; }else{ return 0; } #else return !sqlite3Atoi64(z, pResult, length, enc); #endif /* SQLITE_OMIT_FLOATING_POINT */ } /* ** Compare the 19-character string zNum against the text representation ................................................................................ /* ** Convert zNum to a 64-bit signed integer. zNum must be decimal. This ** routine does *not* accept hexadecimal notation. ** ** Returns: ** ** -1 Not even a prefix of the input text looks like an integer ** 0 Successful transformation. Fits in a 64-bit signed integer. ** 1 Excess non-space text after the integer value ** 2 Integer too large for a 64-bit signed integer or is malformed ** 3 Special case of 9223372036854775808 ** ** length is the number of bytes in the string (bytes, not characters). ** The string is not necessarily zero-terminated. The encoding is ................................................................................ *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; }else if( neg ){ *pNum = -(i64)u; }else{ *pNum = (i64)u; } rc = 0; if( i==0 && zStart==zNum ){ /* No digits */ rc = -1; }else if( nonNum ){ /* UTF16 with high-order bytes non-zero */ rc = 1; }else if( &zNum[i]<zEnd ){ /* Extra bytes at the end */ int jj = i; do{ if( !sqlite3Isspace(zNum[jj]) ){ rc = 1; /* Extra non-space text after the integer */ break; |
Changes to src/vdbe.c.
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 ... 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 .... 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 .... 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 .... 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 .... 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 |
*/ static void applyNumericAffinity(Mem *pRec, int bTryForInt){ double rValue; u8 enc = pRec->enc; int rc; assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real|MEM_IntReal))==MEM_Str ); rc = sqlite3AtoF(pRec->z, &rValue, pRec->n, enc); if( rc==0 ) return; if( rc==1 && alsoAnInt(pRec, rValue, &pRec->u.i) ){ pRec->flags |= MEM_Int; }else{ pRec->u.r = rValue; pRec->flags |= MEM_Real; if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec); } ................................................................................ /* ** pMem currently only holds a string type (or maybe a BLOB that we can ** interpret as a string if we want to). Compute its corresponding ** numeric type, if has one. Set the pMem->u.r and pMem->u.i fields ** accordingly. */ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ); assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ); ExpandBlob(pMem); if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){ return 0; } if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==0 ){ return MEM_Int; } return MEM_Real; } /* ** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or ................................................................................ ** If either operand is NULL, the result is NULL. */ case OP_Add: /* same as TK_PLUS, in1, in2, out3 */ case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */ case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */ case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ char bIntint; /* Started out as two integer operands */ u16 flags; /* Combined MEM_* flags from both inputs */ u16 type1; /* Numeric type of left operand */ u16 type2; /* Numeric type of right operand */ i64 iA; /* Integer value of left operand */ i64 iB; /* Integer value of right operand */ double rA; /* Real value of left operand */ double rB; /* Real value of right operand */ ................................................................................ pIn2 = &aMem[pOp->p2]; type2 = numericType(pIn2); pOut = &aMem[pOp->p3]; flags = pIn1->flags | pIn2->flags; if( (type1 & type2 & MEM_Int)!=0 ){ iA = pIn1->u.i; iB = pIn2->u.i; bIntint = 1; switch( pOp->opcode ){ case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break; case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break; case OP_Multiply: if( sqlite3MulInt64(&iB,iA) ) goto fp_math; break; case OP_Divide: { if( iA==0 ) goto arithmetic_result_is_null; if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math; ................................................................................ } } pOut->u.i = iB; MemSetTypeFlag(pOut, MEM_Int); }else if( (flags & MEM_Null)!=0 ){ goto arithmetic_result_is_null; }else{ bIntint = 0; fp_math: rA = sqlite3VdbeRealValue(pIn1); rB = sqlite3VdbeRealValue(pIn2); switch( pOp->opcode ){ case OP_Add: rB += rA; break; case OP_Subtract: rB -= rA; break; case OP_Multiply: rB *= rA; break; ................................................................................ MemSetTypeFlag(pOut, MEM_Int); #else if( sqlite3IsNaN(rB) ){ goto arithmetic_result_is_null; } pOut->u.r = rB; MemSetTypeFlag(pOut, MEM_Real); if( ((type1|type2)&(MEM_Real|MEM_IntReal))==0 && !bIntint ){ sqlite3VdbeIntegerAffinity(pOut); } #endif } break; arithmetic_result_is_null: sqlite3VdbeMemSetNull(pOut); break; |
| > > | > > > | > > | < > > < < < < < < |
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 ... 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 .... 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 .... 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 .... 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 .... 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 |
*/ static void applyNumericAffinity(Mem *pRec, int bTryForInt){ double rValue; u8 enc = pRec->enc; int rc; assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real|MEM_IntReal))==MEM_Str ); rc = sqlite3AtoF(pRec->z, &rValue, pRec->n, enc); if( rc<=0 ) return; if( rc==1 && alsoAnInt(pRec, rValue, &pRec->u.i) ){ pRec->flags |= MEM_Int; }else{ pRec->u.r = rValue; pRec->flags |= MEM_Real; if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec); } ................................................................................ /* ** pMem currently only holds a string type (or maybe a BLOB that we can ** interpret as a string if we want to). Compute its corresponding ** numeric type, if has one. Set the pMem->u.r and pMem->u.i fields ** accordingly. */ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ int rc; sqlite3_int64 ix; assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ); assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ); ExpandBlob(pMem); rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); if( rc<=0 ){ if( rc==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1 ){ pMem->u.i = ix; return MEM_Int; }else{ return MEM_Real; } }else if( rc==1 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)==0 ){ pMem->u.i = ix; return MEM_Int; } return MEM_Real; } /* ** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or ................................................................................ ** If either operand is NULL, the result is NULL. */ case OP_Add: /* same as TK_PLUS, in1, in2, out3 */ case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */ case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */ case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ u16 flags; /* Combined MEM_* flags from both inputs */ u16 type1; /* Numeric type of left operand */ u16 type2; /* Numeric type of right operand */ i64 iA; /* Integer value of left operand */ i64 iB; /* Integer value of right operand */ double rA; /* Real value of left operand */ double rB; /* Real value of right operand */ ................................................................................ pIn2 = &aMem[pOp->p2]; type2 = numericType(pIn2); pOut = &aMem[pOp->p3]; flags = pIn1->flags | pIn2->flags; if( (type1 & type2 & MEM_Int)!=0 ){ iA = pIn1->u.i; iB = pIn2->u.i; switch( pOp->opcode ){ case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break; case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break; case OP_Multiply: if( sqlite3MulInt64(&iB,iA) ) goto fp_math; break; case OP_Divide: { if( iA==0 ) goto arithmetic_result_is_null; if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math; ................................................................................ } } pOut->u.i = iB; MemSetTypeFlag(pOut, MEM_Int); }else if( (flags & MEM_Null)!=0 ){ goto arithmetic_result_is_null; }else{ fp_math: rA = sqlite3VdbeRealValue(pIn1); rB = sqlite3VdbeRealValue(pIn2); switch( pOp->opcode ){ case OP_Add: rB += rA; break; case OP_Subtract: rB -= rA; break; case OP_Multiply: rB *= rA; break; ................................................................................ MemSetTypeFlag(pOut, MEM_Int); #else if( sqlite3IsNaN(rB) ){ goto arithmetic_result_is_null; } pOut->u.r = rB; MemSetTypeFlag(pOut, MEM_Real); #endif } break; arithmetic_result_is_null: sqlite3VdbeMemSetNull(pOut); break; |
Changes to src/vdbemem.c.
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 |
int sqlite3VdbeMemNumerify(Mem *pMem){ testcase( pMem->flags & MEM_Int ); testcase( pMem->flags & MEM_Real ); testcase( pMem->flags & MEM_IntReal ); testcase( pMem->flags & MEM_Null ); if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){ int rc; assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc); if( rc==0 ){ MemSetTypeFlag(pMem, MEM_Int); }else{ i64 i = pMem->u.i; sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); if( rc==1 && sqlite3RealSameAsInt(pMem->u.r, i) ){ pMem->u.i = i; MemSetTypeFlag(pMem, MEM_Int); }else{ MemSetTypeFlag(pMem, MEM_Real); } } } assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))!=0 ); pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero); return SQLITE_OK; } |
> < < < < < | < > > | > > > > > |
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 |
int sqlite3VdbeMemNumerify(Mem *pMem){ testcase( pMem->flags & MEM_Int ); testcase( pMem->flags & MEM_Real ); testcase( pMem->flags & MEM_IntReal ); testcase( pMem->flags & MEM_Null ); if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){ int rc; sqlite3_int64 ix; assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); if( rc<=0 ){ if( rc==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1 ){ pMem->u.i = ix; MemSetTypeFlag(pMem, MEM_Int); }else{ MemSetTypeFlag(pMem, MEM_Real); } }else if( rc==1 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)==0 ){ pMem->u.i = ix; MemSetTypeFlag(pMem, MEM_Int); }else{ MemSetTypeFlag(pMem, MEM_Real); } } assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))!=0 ); pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero); return SQLITE_OK; } |
Changes to test/cast.test.
383 384 385 386 387 388 389 390 391 |
INSERT INTO t1 VALUES ('9000000000000000001'), ('9000000000000000001 '), (' 9000000000000000001'), (' 9000000000000000001 '); SELECT * FROM t1; } {9000000000000000001 9000000000000000001 9000000000000000001 9000000000000000001} finish_test |
> > > > > > > > > > > > > > > > > > > > > > > > > > > |
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 |
INSERT INTO t1 VALUES ('9000000000000000001'), ('9000000000000000001 '), (' 9000000000000000001'), (' 9000000000000000001 '); SELECT * FROM t1; } {9000000000000000001 9000000000000000001 9000000000000000001 9000000000000000001} # 2019-06-07 # https://www.sqlite.org/src/info/4c2d7639f076aa7c do_execsql_test case-7.1 { SELECT CAST('-' AS NUMERIC); } {0} do_execsql_test case-7.2 { SELECT CAST('-0' AS NUMERIC); } {0} do_execsql_test case-7.3 { SELECT CAST('+' AS NUMERIC); } {0} do_execsql_test case-7.4 { SELECT CAST('/' AS NUMERIC); } {0} # 2019-06-07 # https://www.sqlite.org/src/info/e8bedb2a184001bb do_execsql_test case-7.10 { SELECT '' - 2851427734582196970; } {-2851427734582196970} do_execsql_test case-7.11 { SELECT 0 - 2851427734582196970; } {-2851427734582196970} do_execsql_test case-7.12 { SELECT '' - 1; } {-1} finish_test |
Changes to test/e_expr.test.
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
....
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
|
# EVIDENCE-OF: R-09295-61337 Casting a TEXT or BLOB value into NUMERIC # first does a forced conversion into REAL but then further converts the # result into INTEGER if and only if the conversion from REAL to INTEGER # is lossless and reversible. # do_expr_test e_expr-32.1.1 { CAST('45' AS NUMERIC) } integer 45 do_expr_test e_expr-32.1.2 { CAST('45.0' AS NUMERIC) } integer 45 do_expr_test e_expr-32.1.3 { CAST('45.2' AS NUMERIC) } real 45.2 do_expr_test e_expr-32.1.4 { CAST('11abc' AS NUMERIC) } integer 11 do_expr_test e_expr-32.1.5 { CAST('11.1abc' AS NUMERIC) } real 11.1 # EVIDENCE-OF: R-30347-18702 Casting a REAL or INTEGER value to NUMERIC # is a no-op, even if a real value could be losslessly converted to an # integer. ................................................................................ SELECT typeof(CAST(x AS NUMERIC)), CAST(x AS NUMERIC)||'' FROM t1; } [list \ integer 9000000000000000001 \ integer 9000000000000000001 \ integer 9000000000000000001 \ integer 9000000000000000001 \ integer 9000000000000000001 \ integer 9000000000000000001 \ integer 9223372036854775807 \ integer 9223372036854775807 \ integer 9223372036854775807 \ real 9.22337203685478e+18 \ real 9.22337203685478e+18 \ integer 9223372036854775807 \ integer 9223372036854775807 \ integer -5 \ integer -5 \ ] # EVIDENCE-OF: R-64550-29191 Note that the result from casting any # non-BLOB value into a BLOB and the result from casting any BLOB value # into a non-BLOB value may be different depending on whether the # database encoding is UTF-8, UTF-16be, or UTF-16le. # |
|
|
|
|
|
|
|
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
....
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
|
# EVIDENCE-OF: R-09295-61337 Casting a TEXT or BLOB value into NUMERIC # first does a forced conversion into REAL but then further converts the # result into INTEGER if and only if the conversion from REAL to INTEGER # is lossless and reversible. # do_expr_test e_expr-32.1.1 { CAST('45' AS NUMERIC) } integer 45 do_expr_test e_expr-32.1.2 { CAST('45.0' AS NUMERIC) } real 45.0 do_expr_test e_expr-32.1.3 { CAST('45.2' AS NUMERIC) } real 45.2 do_expr_test e_expr-32.1.4 { CAST('11abc' AS NUMERIC) } integer 11 do_expr_test e_expr-32.1.5 { CAST('11.1abc' AS NUMERIC) } real 11.1 # EVIDENCE-OF: R-30347-18702 Casting a REAL or INTEGER value to NUMERIC # is a no-op, even if a real value could be losslessly converted to an # integer. ................................................................................ SELECT typeof(CAST(x AS NUMERIC)), CAST(x AS NUMERIC)||'' FROM t1; } [list \ integer 9000000000000000001 \ integer 9000000000000000001 \ integer 9000000000000000001 \ integer 9000000000000000001 \ integer 9000000000000000001 \ real 9.0e+18 \ integer 9223372036854775807 \ integer 9223372036854775807 \ integer 9223372036854775807 \ real 9.22337203685478e+18 \ real 9.22337203685478e+18 \ real 9.22337203685478e+18 \ real 9.22337203685478e+18 \ real -5.0 \ real -5.0 \ ] # EVIDENCE-OF: R-64550-29191 Note that the result from casting any # non-BLOB value into a BLOB and the result from casting any BLOB value # into a non-BLOB value may be different depending on whether the # database encoding is UTF-8, UTF-16be, or UTF-16le. # |
Changes to test/tkt-a8a0d2996a.test.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
SELECT '100x'+'-2y'; } {98} do_execsql_test 4.3 { SELECT '100x'+'4.5y'; } {104.5} do_execsql_test 4.4 { SELECT '-9223372036854775807x'-'1x'; } {-9.22337203685478e+18} do_execsql_test 4.5 { SELECT '9223372036854775806x'+'1x'; } {9.22337203685478e+18} do_execsql_test 4.6 { SELECT '1234x'/'10y'; } {123.4} finish_test |
| | | | |
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
SELECT '100x'+'-2y'; } {98} do_execsql_test 4.3 { SELECT '100x'+'4.5y'; } {104.5} do_execsql_test 4.4 { SELECT '-9223372036854775807x'-'1x'; } {-9223372036854775808} do_execsql_test 4.5 { SELECT '9223372036854775806x'+'1x'; } {9223372036854775807} do_execsql_test 4.6 { SELECT '1234x'/'10y', '1234x'/'10.y', '1234x'/'1e1y'; } {123 123.4 123.4} finish_test |