Modify ↓
Ticket #339 (closed defect: fixed)
RangeQuery bounds comparison does not handle negative numbers well
| Reported by: | philippe@… | Owned by: | somebody |
|---|---|---|---|
| Priority: | major | Milestone: | |
| Component: | component1 | Version: | |
| Keywords: | Cc: |
Description
I'm using RangeQuery? to query against positive and negative floats, and the comparison function to assert the bounds are ok uses strcmp, therefore it doesn't work well with negative numbers.
For positive numbers it works ok because the ascii codes of 1 is smaller than 2 in a string.
ferret/ruby/ext/r_search.c: line 1058
if (*uterm && *lterm && (strcmp(*uterm, *lterm) < 0)) {
rb_raise(rb_eArgError,
"The upper bound should greater than the lower bound."
" %s > %s", *lterm, *uterm);
}
Maybe the code should test if the string is a number and just use a regular mathematics comparison.
Ideally the code would also handle floats!
Attachments
Change History
Note: See
TracTickets for help on using
tickets.

This is a little more difficult than it seems. There is also the problem of performance. When searching for ascii ranges the data is naturally ordered in the index so you scan skip right to the first term in the index and stop as soon as reach the last term. When doing integer or float comparisons you need to check all terms in the range from +.0 to 999999999999 (or there abouts). You also need to convert every one of those terms to a number to do the comparison.
So I decided to make a separate query to handle typed ranges call Ferret::Search::TypedRangeQuery?. This will work for integer, floats, hexadecimals and both positive and negative numbers. I've also made it the default range query for the Ferret::Index::Index class as it is probably closest to what the user expects. There will however still be cases where you'll want to stick with Ferret::Search::RangeQuery?, especially if you have a particularly large index.
Here is an example of TypedRangeQuery? usage;