nitrite-java icon indicating copy to clipboard operation
nitrite-java copied to clipboard

Inconsistent filtering of numeric values

Open enitram opened this issue 1 year ago • 3 comments

When comparing numbers of different types, nitrite returns different results depending on the filter (eq, lte, gte) and if the value was indexed.

Here is a small example comparing int and long:

        Nitrite db = Nitrite.builder().openOrCreate();
        NitriteCollection collection = db.getCollection("myCollection");

        Document doc = Document.createDocument("value", 42);
        collection.insert(doc);

//        assert collection.find(FluentFilter.where("value").eq(42L)).size() == 1;  // FAIL
        assert collection.find(FluentFilter.where("value").lte(42L)).size() == 1; // SUCCESS
        assert collection.find(FluentFilter.where("value").gte(42L)).size() == 1; // SUCCESS

        collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "value");

//        assert collection.find(FluentFilter.where("value").eq(42L)).size() == 1;  // FAIL
//        assert collection.find(FluentFilter.where("value").lte(42L)).size() == 1;  // FAIL
//        assert collection.find(FluentFilter.where("value").gte(42L)).size() == 1; // FAIL

        db.close();

This was tested with nitrite 4.3.0 and also shows the same results when comparing int and double.

enitram avatar Oct 23 '24 20:10 enitram

I'll take a look at it.

anidotnet avatar Oct 24 '24 05:10 anidotnet

@anidotnet I compared the implementations of apply in EqualsFilter.java and LesserEqualFilter.java and once I discovered this section, it seemed clear that this is part of the problem. https://github.com/nitrite/nitrite-java/blob/3fbb501ba6ff086339377bb04f571b4004ac9bfe/nitrite/src/main/java/org/dizitart/no2/common/util/ObjectUtils.java#L129-L132

After all, the check for instanceof Number is specifically a recognition that different subclasses are still directly comparable. I wrote a little unit test locally based on @enitram's repro snippet above and I confirmed that commenting out lines 130-132 causes the first assert to no longer fail. 🎉 (Of course, it does make a few other tests elsewhere in the project fail, and now I'm out of my depth on the internal logic of Nitrite's filter abstractions.)

I hope this is at least somewhat helpful! 🙇

leoger avatar Nov 16 '24 07:11 leoger

Thanks a lot @leoger for your analysis. I am still quite busy with other urgent engagement. Once I get some times, I'll take a look at this issue.

anidotnet avatar Nov 16 '24 08:11 anidotnet