Skip to content

Commit

Permalink
Strict Number Parsing (#116)
Browse files Browse the repository at this point in the history
* upgrade to gradle 8.3

* update numeric parsing to be more strict and add test cases.
* floating points can no longer be used to search integer fields (i.e. intField:100.434 will not work)
* values such as 100a will be not be parsed as 100 (i.e. intField:100a will not work)
* values like intField:10.1332/3232.323.1 will no longer search for intField:10

* add another test case showing intField being ignored when searching with a double value
  • Loading branch information
mdavis95 authored Aug 23, 2023
1 parent c7dc233 commit fb59ccc
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 7 deletions.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import org.apache.lucene.queryparser.flexible.standard.nodes.TermRangeQueryNode;

import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.List;
import java.util.Locale;

Expand Down Expand Up @@ -104,11 +104,12 @@ else if (node instanceof TermRangeQueryNode termRangeNode) {

private static Number parseNumber(String text, NumberFormat numberFormat, FieldType fieldType) {
Number number = null;
if (text.length() > 0) {
if (!text.isEmpty()) {
if (FieldTypeUtil.isNumericFieldType(fieldType)) {

try {
number = numberFormat.parse(text);
ParsePosition parsePosition = new ParsePosition(0);
number = numberFormat.parse(text, parsePosition);
if (parsePosition.getIndex() == text.length()) {

if (FieldTypeUtil.isNumericIntFieldType(fieldType)) {
number = number.intValue();
Expand All @@ -123,9 +124,10 @@ else if (FieldTypeUtil.isNumericDoubleFieldType(fieldType)) {
number = number.doubleValue();
}
}
catch (ParseException e) {

else {
number = null;
}

}
else if (FieldTypeUtil.isBooleanFieldType(fieldType)) {
number = BooleanUtil.getStringAsBooleanInt(text);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.extension.RegisterExtension;

import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Locale;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class NumericSetTest {
Expand Down Expand Up @@ -228,6 +230,75 @@ public void searchTest() throws Exception {
searchResult = zuliaWorkPool.search(search);
Assertions.assertEquals(1, searchResult.getTotalHits());

search = new Search(NUMERIC_SET_TEST);
search.addQuery(new FilterQuery("intField:[1 TO 10]"));
searchResult = zuliaWorkPool.search(search);
Assertions.assertEquals(4, searchResult.getTotalHits());

search = new Search(NUMERIC_SET_TEST);
search.addQuery(new FilterQuery("intField:[1a TO 10]")); // turns in a match no document query if invalid integer given
searchResult = zuliaWorkPool.search(search);
Assertions.assertEquals(0, searchResult.getTotalHits());

search = new Search(NUMERIC_SET_TEST);
search.addQuery(new FilterQuery("intField:[1 TO 10a]")); // turns in a match no document query if invalid integer given
searchResult = zuliaWorkPool.search(search);
Assertions.assertEquals(0, searchResult.getTotalHits());

search = new Search(NUMERIC_SET_TEST);
search.addQuery(new FilterQuery("intField:[1.0 TO 10]")); // turns in a match no document query if floating point number given to int field
searchResult = zuliaWorkPool.search(search);
Assertions.assertEquals(0, searchResult.getTotalHits());

search = new Search(NUMERIC_SET_TEST);
search.addQuery(new FilterQuery("intField:[1 TO 10.0]")); // turns in a match no document query if floating point number given to int field
searchResult = zuliaWorkPool.search(search);
Assertions.assertEquals(0, searchResult.getTotalHits());

search = new Search(NUMERIC_SET_TEST);
search.addQuery(new FilterQuery("floatField:[1 TO 132]")); // integer searches are allowed against floating point numbers
searchResult = zuliaWorkPool.search(search);
Assertions.assertEquals(4, searchResult.getTotalHits());

search = new Search(NUMERIC_SET_TEST);
search.addQuery(new FilterQuery("floatField:[1.1 TO 131.9]"));
searchResult = zuliaWorkPool.search(search);
Assertions.assertEquals(2, searchResult.getTotalHits());

search = new Search(NUMERIC_SET_TEST);
search.addQuery(new FilterQuery("floatField:[1.1a TO 131.9]")); // turns in a match no document query if invalid floating point given
searchResult = zuliaWorkPool.search(search);
Assertions.assertEquals(0, searchResult.getTotalHits());

search = new Search(NUMERIC_SET_TEST);
search.addQuery(new FilterQuery("floatField:[1.1 TO 131.9a]")); // turns in a match no document query if invalid floating point given
searchResult = zuliaWorkPool.search(search);
Assertions.assertEquals(0, searchResult.getTotalHits());

NumberFormat integerFormat = NumberFormat.getIntegerInstance(Locale.ROOT);
search = new Search(NUMERIC_SET_TEST);
search.addQuery(new FilterQuery("intField:[" + integerFormat.format(52) + " TO " + integerFormat.format(12332) + "]")); // gives 12,232 in US locale
searchResult = zuliaWorkPool.search(search);
Assertions.assertEquals(2, searchResult.getTotalHits());

search = new Search(NUMERIC_SET_TEST);
search.addQuery(
new FilterQuery("longField:[" + integerFormat.format(5) + " TO " + integerFormat.format(23232323L) + "]")); // gives 23,232,323L in US locale
searchResult = zuliaWorkPool.search(search);
Assertions.assertEquals(3, searchResult.getTotalHits());

NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.ROOT);

search = new Search(NUMERIC_SET_TEST);
search.addQuery(new FilterQuery("doubleField:[" + numberFormat.format(2.01) + " TO " + numberFormat.format(2444.0) + "]")); // gives 2,444 in US locale
searchResult = zuliaWorkPool.search(search);
Assertions.assertEquals(2, searchResult.getTotalHits());

search = new Search(NUMERIC_SET_TEST);
search.addQuery(new FilterQuery(
"intField,doubleField:[" + numberFormat.format(2.01) + " TO " + numberFormat.format(2444.0) + "]")); // intField is ignored for the double value
searchResult = zuliaWorkPool.search(search);
Assertions.assertEquals(2, searchResult.getTotalHits());
}

@Test
Expand Down
2 changes: 2 additions & 0 deletions zulia-server/src/test/java/io/zulia/server/test/node/T.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
package io.zulia.server.test.node;public class T {
}

0 comments on commit fb59ccc

Please sign in to comment.