Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch int-float-precision Excluding Merge-Ins
This is equivalent to a diff from 840cbda886 to 7a9988d38c
2015-11-06
| ||
19:53 | Enforce consistent comparison results between integer and floating point values. Fix for ticket [38a97a87a6e4e83]. (check-in: 849e686da2 user: drh tags: trunk) | |
17:59 | Merge the fixes and tests for the ieee754 extension. (Closed-Leaf check-in: 7a9988d38c user: drh tags: int-float-precision) | |
17:28 | A proposed patch for working around a bug in the optimizer for the HP compiler found on HP/UX Itanium. (Closed-Leaf check-in: 8a171548e4 user: drh tags: hp-optimizer-fix) | |
17:01 | Test cases for the ieee754 extension. (check-in: 840cbda886 user: drh tags: trunk) | |
14:59 | A different approach to handling integer/float comparisons. This seems to work better on systems where "long double" and "double" are the same type, but still needs refinement and testing. (check-in: a3f7614b20 user: drh tags: int-float-precision) | |
12:50 | Have fts5 load its configuration from the xConnect() method is invoked. This ensures that the very first query run uses the correct value of the 'rank' option. (check-in: 33e6606f5e user: dan tags: trunk) | |
Changes to src/test1.c.
︙ | ︙ | |||
7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS { "sqlite3_stmt_scanstatus", test_stmt_scanstatus, 0 }, { "sqlite3_stmt_scanstatus_reset", test_stmt_scanstatus_reset, 0 }, #endif }; static int bitmask_size = sizeof(Bitmask)*8; int i; extern int sqlite3_sync_count, sqlite3_fullsync_count; extern int sqlite3_opentemp_count; extern int sqlite3_like_count; extern int sqlite3_xferopt_count; extern int sqlite3_pager_readdb_count; extern int sqlite3_pager_writedb_count; | > | 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS { "sqlite3_stmt_scanstatus", test_stmt_scanstatus, 0 }, { "sqlite3_stmt_scanstatus_reset", test_stmt_scanstatus_reset, 0 }, #endif }; static int bitmask_size = sizeof(Bitmask)*8; static int longdouble_size = sizeof(LONGDOUBLE_TYPE); int i; extern int sqlite3_sync_count, sqlite3_fullsync_count; extern int sqlite3_opentemp_count; extern int sqlite3_like_count; extern int sqlite3_xferopt_count; extern int sqlite3_pager_readdb_count; extern int sqlite3_pager_writedb_count; |
︙ | ︙ | |||
7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 | (char*)&sqlite_static_bind_nbyte, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_temp_directory", (char*)&sqlite3_temp_directory, TCL_LINK_STRING); Tcl_LinkVar(interp, "sqlite_data_directory", (char*)&sqlite3_data_directory, TCL_LINK_STRING); Tcl_LinkVar(interp, "bitmask_size", (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY); Tcl_LinkVar(interp, "sqlite_sync_count", (char*)&sqlite3_sync_count, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_fullsync_count", (char*)&sqlite3_fullsync_count, TCL_LINK_INT); #if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_TEST) Tcl_LinkVar(interp, "sqlite_fts3_enable_parentheses", (char*)&sqlite3_fts3_enable_parentheses, TCL_LINK_INT); #endif return TCL_OK; } | > > | 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 | (char*)&sqlite_static_bind_nbyte, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_temp_directory", (char*)&sqlite3_temp_directory, TCL_LINK_STRING); Tcl_LinkVar(interp, "sqlite_data_directory", (char*)&sqlite3_data_directory, TCL_LINK_STRING); Tcl_LinkVar(interp, "bitmask_size", (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY); Tcl_LinkVar(interp, "longdouble_size", (char*)&longdouble_size, TCL_LINK_INT|TCL_LINK_READ_ONLY); Tcl_LinkVar(interp, "sqlite_sync_count", (char*)&sqlite3_sync_count, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_fullsync_count", (char*)&sqlite3_fullsync_count, TCL_LINK_INT); #if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_TEST) Tcl_LinkVar(interp, "sqlite_fts3_enable_parentheses", (char*)&sqlite3_fts3_enable_parentheses, TCL_LINK_INT); #endif return TCL_OK; } |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 | */ static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){ int c = memcmp(pB1->z, pB2->z, pB1->n>pB2->n ? pB2->n : pB1->n); if( c ) return c; return pB1->n - pB2->n; } /* ** Compare the values contained by the two memory cells, returning ** negative, zero or positive if pMem1 is less than, equal to, or greater ** than pMem2. Sorting order is NULL's first, followed by numbers (integers ** and reals) sorted numerically, followed by text ordered by the collating ** sequence pColl and finally blob's ordered by memcmp(). | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 | */ static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){ int c = memcmp(pB1->z, pB2->z, pB1->n>pB2->n ? pB2->n : pB1->n); if( c ) return c; return pB1->n - pB2->n; } /* ** Do a comparison between a 64-bit signed integer and a 64-bit floating-point ** number. Return negative, zero, or positive if the first (i64) is less than, ** equal to, or greater than the second (double). */ static int sqlite3IntFloatCompare(i64 i, double r){ if( sizeof(LONGDOUBLE_TYPE)>8 ){ LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i; if( x<r ) return -1; if( x>r ) return +1; return 0; }else{ i64 y; double s; if( r<-9223372036854775808.0 ) return +1; if( r>9223372036854775807.0 ) return -1; y = (i64)r; if( i<y ) return -1; if( i>y ){ if( y==SMALLEST_INT64 && r>0.0 ) return -1; return +1; } s = (double)i; if( s<r ) return -1; if( s>r ) return +1; return 0; } } /* ** Compare the values contained by the two memory cells, returning ** negative, zero or positive if pMem1 is less than, equal to, or greater ** than pMem2. Sorting order is NULL's first, followed by numbers (integers ** and reals) sorted numerically, followed by text ordered by the collating ** sequence pColl and finally blob's ordered by memcmp(). |
︙ | ︙ | |||
3656 3657 3658 3659 3660 3661 3662 | /* If one value is NULL, it is less than the other. If both values ** are NULL, return 0. */ if( combined_flags&MEM_Null ){ return (f2&MEM_Null) - (f1&MEM_Null); } | | < < < | | | > > > | > | | | | > | < | | | | | < < > | | 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 | /* If one value is NULL, it is less than the other. If both values ** are NULL, return 0. */ if( combined_flags&MEM_Null ){ return (f2&MEM_Null) - (f1&MEM_Null); } /* At least one of the two values is a number */ if( combined_flags&(MEM_Int|MEM_Real) ){ if( (f1 & f2 & MEM_Int)!=0 ){ if( pMem1->u.i < pMem2->u.i ) return -1; if( pMem1->u.i > pMem2->u.i ) return +1; return 0; } if( (f1 & f2 & MEM_Real)!=0 ){ if( pMem1->u.r < pMem2->u.r ) return -1; if( pMem1->u.r > pMem2->u.r ) return +1; return 0; } if( (f1&MEM_Int)!=0 ){ if( (f2&MEM_Real)!=0 ){ return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r); }else{ return -1; } } if( (f1&MEM_Real)!=0 ){ if( (f2&MEM_Int)!=0 ){ return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r); }else{ return -1; } } return +1; } /* If one value is a string and the other is a blob, the string is less. ** If both are strings, compare using the collating functions. */ if( combined_flags&MEM_Str ){ if( (f1 & MEM_Str)==0 ){ |
︙ | ︙ | |||
3834 3835 3836 3837 3838 3839 3840 | serial_type = aKey1[idx1]; testcase( serial_type==12 ); if( serial_type>=10 ){ rc = +1; }else if( serial_type==0 ){ rc = -1; }else if( serial_type==7 ){ | < < | < < < | 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 | serial_type = aKey1[idx1]; testcase( serial_type==12 ); if( serial_type>=10 ){ rc = +1; }else if( serial_type==0 ){ rc = -1; }else if( serial_type==7 ){ sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r); }else{ i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]); i64 rhs = pRhs->u.i; if( lhs<rhs ){ rc = -1; }else if( lhs>rhs ){ rc = +1; |
︙ | ︙ | |||
3864 3865 3866 3867 3868 3869 3870 | ** numbers). Types 10 and 11 are currently "reserved for future ** use", so it doesn't really matter what the results of comparing ** them to numberic values are. */ rc = +1; }else if( serial_type==0 ){ rc = -1; }else{ | < < | < < < < | | | > > > | 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 | ** numbers). Types 10 and 11 are currently "reserved for future ** use", so it doesn't really matter what the results of comparing ** them to numberic values are. */ rc = +1; }else if( serial_type==0 ){ rc = -1; }else{ sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); if( serial_type==7 ){ if( mem1.u.r<pRhs->u.r ){ rc = -1; }else if( mem1.u.r>pRhs->u.r ){ rc = +1; } }else{ rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r); } } } /* RHS is a string */ else if( pRhs->flags & MEM_Str ){ getVarint32(&aKey1[idx1], serial_type); |
︙ | ︙ | |||
4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 | int nKey1, const void *pKey1, /* Left key */ UnpackedRecord *pPKey2 /* Right key */ ){ const u8 *aKey1 = (const u8*)pKey1; int serial_type; int res; vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo); getVarint32(&aKey1[1], serial_type); if( serial_type<12 ){ res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */ }else if( !(serial_type & 0x01) ){ res = pPKey2->r2; /* (pKey1/nKey1) is a blob */ }else{ | > | 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 | int nKey1, const void *pKey1, /* Left key */ UnpackedRecord *pPKey2 /* Right key */ ){ const u8 *aKey1 = (const u8*)pKey1; int serial_type; int res; assert( pPKey2->aMem[0].flags & MEM_Str ); vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo); getVarint32(&aKey1[1], serial_type); if( serial_type<12 ){ res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */ }else if( !(serial_type & 0x01) ){ res = pPKey2->r2; /* (pKey1/nKey1) is a blob */ }else{ |
︙ | ︙ |
Changes to test/atof1.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 | # # Tests of the sqlite3AtoF() function. # set testdir [file dirname $argv0] source $testdir/tester.tcl | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # # Tests of the sqlite3AtoF() function. # set testdir [file dirname $argv0] source $testdir/tester.tcl if {$::longdouble_size<=8} { finish_test return } expr srand(1) for {set i 1} {$i<20000} {incr i} { set pow [expr {int((rand()-0.5)*100)}] |
︙ | ︙ |
Added test/numindex1.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | # 2015-11-05 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements tests for indexes on large numeric values. # set testdir [file dirname $argv0] source $testdir/tester.tcl # Test cases from Zsbán Ambrus: # do_execsql_test numindex1-1.1 { CREATE TABLE t1(a INTEGER PRIMARY KEY, b); CREATE INDEX t1b ON t1(b); INSERT INTO t1(a,b) VALUES(100, 356282677878746339); INSERT INTO t1(a,b) VALUES(50, 356282677878746339.0); INSERT INTO t1(a,b) VALUES(0, 356282677878746340); DELETE FROM t1 WHERE a=50; PRAGMA integrity_check; } {ok} do_execsql_test numindex1-1.2 { CREATE TABLE t2(a,b); INSERT INTO t2(a,b) VALUES('b', 1<<58), ('c', (1<<58)+1e-7), ('d', (1<<58)+1); SELECT a, b, typeof(b), '|' FROM t2 ORDER BY +a; } {b 288230376151711744 integer | c 2.88230376151712e+17 real | d 288230376151711745 integer |} do_execsql_test numindex1-1.3 { SELECT x.a || CASE WHEN x.b==y.b THEN '==' ELSE '<>' END || y.a FROM t2 AS x, t2 AS y ORDER BY +x.a, +x.b; } {b==b b==c b<>d c==b c==c c<>d d<>b d<>c d==d} # New test cases # do_execsql_test numindex1-2.1 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(a INTEGER PRIMARY KEY,b); CREATE INDEX t1b ON t1(b); WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100) INSERT INTO t1(a,b) SELECT x, 10000000000000004.0 FROM c WHERE x NOT IN (23,37); INSERT INTO t1(a,b) VALUES(23,10000000000000005); INSERT INTO t1(a,b) VALUES(37,10000000000000003); DELETE FROM t1 WHERE a NOT IN (23,37); PRAGMA integrity_check; } {ok} do_execsql_test numindex1-3.1 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(a INTEGER PRIMARY KEY,b); CREATE INDEX t1b ON t1(b); WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<20) INSERT INTO t1(a,b) SELECT x, 100000000000000005.0 FROM c WHERE x NOT IN (3,5,7,11,13,17,19); INSERT INTO t1(a,b) VALUES(3,100000000000000005); INSERT INTO t1(a,b) VALUES(5,100000000000000000); INSERT INTO t1(a,b) VALUES(7,100000000000000008); INSERT INTO t1(a,b) VALUES(11,100000000000000006); INSERT INTO t1(a,b) VALUES(13,100000000000000001); INSERT INTO t1(a,b) VALUES(17,100000000000000004); INSERT INTO t1(a,b) VALUES(19,100000000000000003); PRAGMA integrity_check; } {ok} do_execsql_test numindex1-3.2 { SELECT a FROM t1 ORDER BY b; } {1 2 4 5 6 8 9 10 12 14 15 16 18 20 13 19 17 3 11 7} finish_test |