Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix an off-by-one problem with encoding real values into index keys. Add a test for sorting numeric values. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
7017d07feac998fa797c58c27a253ec7 |
User & Date: | dan 2012-04-21 19:19:55.809 |
Context
2012-04-21
| ||
19:59 | Additional comments on the key encoder. Remove an unused variable. check-in: fdaed18ddf user: drh tags: trunk | |
19:19 | Fix an off-by-one problem with encoding real values into index keys. Add a test for sorting numeric values. check-in: 7017d07fea user: dan tags: trunk | |
18:55 | Fixes to the text of the key encoding definition in key_encoding.txt. check-in: ee5b8b8d11 user: drh tags: trunk | |
Changes
Changes to src/vdbecodec.c.
︙ | ︙ | |||
400 401 402 403 404 405 406 | return s.nOut; } /* ** Encode the small positive floating point number r using the key ** encoding. The caller guarantees that r will be less than 1.0 and ** greater than 0.0. | < < < < < < < | | > < | | > > | > > | > | > > > > > | > > > | < > < | 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 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 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 | return s.nOut; } /* ** Encode the small positive floating point number r using the key ** encoding. The caller guarantees that r will be less than 1.0 and ** greater than 0.0. */ static void encodeSmallFloatKey(double r, KeyEncoder *p){ int e = 0; int i, n; assert( r>0.0 && r<1.0 ); while( r<1e-10 ){ r *= 1e8; e+=4; } while( r<0.01 ){ r *= 100.0; e++; } n = sqlite4PutVarint64(p->aOut+p->nOut, e); for(i=0; i<n; i++) p->aOut[i+p->nOut] ^= 0xff; p->nOut += n; for(i=0; i<18 && r!=0.0; i++){ r *= 100.0; int d = r; p->aOut[p->nOut++] = 2*d + 1; r -= d; } p->aOut[p->nOut-1] &= 0xfe; } /* ** Encode the large positive floating point number r using the key ** encoding. The caller guarantees that r will be finite and greater than ** or equal to 1.0. ** ** A floating point value is encoded as an integer exponent E and a ** mantissa M. The original value is equal to (M * 100^E). E is set to ** the smallest value possible without making M greater than or equal ** to 1.0. ** ** Each centimal digit of the mantissa is stored in a byte. If the value ** of the centimal digit is X (hence X>=0 and X<=99) then the byte value ** will be 2*X+1 for every byte of the mantissa, except for the last byte ** which will be 2*X+0. The mantissa must be the minimum number of bytes ** necessary to represent the value; trailing X==0 digits are omitted. ** This means that the mantissa will never contain a byte with the ** value 0x00. ** ** If E is greater than 10, the encoded value consists of E as a varint ** followed by the mantissa as described above. Otherwise, it consists ** of the mantissa only. ** ** The value returned by this function is E. */ static int encodeLargeFloatKey(double r, KeyEncoder *p){ int e = 0; int i, n; assert( r>=1.0 ); while( r>=1e32 && e<=350 ){ r *= 1e-32; e+=16; } while( r>=1e8 && e<=350 ){ r *= 1e-8; e+=4; } while( r>=1.0 && e<=350 ){ r *= 0.01; e++; } if( e>10 ){ n = sqlite4PutVarint64(p->aOut+p->nOut, e); p->nOut += n; } for(i=0; i<18 && r!=0.0; i++){ r *= 100.0; int d = r; p->aOut[p->nOut++] = 2*d + 1; r -= d; } p->aOut[p->nOut-1] &= 0xfe; return e; } /* |
︙ | ︙ |
Changes to test/simple.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 | # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix simple #set sqlite_where_trace 1 # | < | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix simple #set sqlite_where_trace 1 # do_execsql_test 1.0 { PRAGMA table_info = sqlite_master } { 0 type text 0 {} 0 1 name text 0 {} 0 2 tbl_name text 0 {} 0 |
︙ | ︙ | |||
785 786 787 788 789 790 791 | 1 "SELECT * FROM t1 WHERE a = 7" {7 seven} 2 "SELECT * FROM t1 WHERE b = 'seven'" {7 seven} } { do_execsql_test 42.$t.$u $sql $res } } | < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 | 1 "SELECT * FROM t1 WHERE a = 7" {7 seven} 2 "SELECT * FROM t1 WHERE b = 'seven'" {7 seven} } { do_execsql_test 42.$t.$u $sql $res } } #------------------------------------------------------------------------- reset_db do_execsql_test 43.1 { CREATE TABLE t1(a, b); INSERT INTO t1 VALUES('a', 1); INSERT INTO t1 VALUES('b', 4); INSERT INTO t1 VALUES('a', 2); INSERT INTO t1 VALUES('b', 5); } do_execsql_test 43.2 { SELECT a, sum(b) FROM t1 GROUP BY a; } {a 3 b 9} #------------------------------------------------------------------------- # Test sorting numeric values. # reset_db do_execsql_test 44.1 { CREATE TABLE t1(x PRIMARY KEY, y) } do_test 44.2 { set lVal [list] set val 5.0 for {set i 0} {$i < 10} {incr i ; set val [expr {$val*5.0}] } { lappend lVal $val } set val 5 for {set i 0} {$i < 10} {incr i ; set val [expr {$val*5}] } { lappend lVal [expr $val-1] set val [expr {$val*5}] } set val 5.0 for {set i 0} {$i < 10} {incr i ; set val [expr {$val/5.0}] } { lappend lVal $val set val [expr {$val/5.0}] } set lVal2 [list] foreach val $lVal { lappend lVal2 [expr $val * -1] } set lVal [concat $lVal $lVal2] foreach v $lVal { execsql "INSERT INTO t1 VALUES(randomblob(16), $v)" } } {} do_execsql_test 44.3 { SELECT y FROM t1 ORDER BY y; } [lsort -real $lVal] do_execsql_test 44.4 { SELECT count(*) FROM t1; } {60} finish_test |