LUCENE-7219: Make queryparser/xml (Point|LegacyNumeric)RangeQuery builders match the underlying queries' (lower|upper)Term optionality logic. (Kaneshanathan Srivisagan, Christine Poerschke)

This commit is contained in:
Christine Poerschke 2016-04-18 09:58:38 +01:00
parent 9a1880aee8
commit c57db02580
10 changed files with 260 additions and 24 deletions

View File

@ -84,6 +84,10 @@ Bug Fixes
that led to IllegalStateException being thrown when nothing was wrong. that led to IllegalStateException being thrown when nothing was wrong.
(David Smiley, yonik) (David Smiley, yonik)
* LUCENE-7219: Make queryparser/xml (Point|LegacyNumeric)RangeQuery builders
match the underlying queries' (lower|upper)Term optionality logic.
(Kaneshanathan Srivisagan, Christine Poerschke)
Documentation Documentation
* LUCENE-7223: Improve XXXPoint javadocs to make it clear that you * LUCENE-7223: Improve XXXPoint javadocs to make it clear that you

View File

@ -45,14 +45,14 @@ import org.w3c.dom.Element;
* <tr> * <tr>
* <td>lowerTerm</td> * <td>lowerTerm</td>
* <td>Specified by <tt>type</tt></td> * <td>Specified by <tt>type</tt></td>
* <td>Yes</td> * <td>No</td>
* <td>N/A</td> * <td>Null</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>upperTerm</td> * <td>upperTerm</td>
* <td>Specified by <tt>type</tt></td> * <td>Specified by <tt>type</tt></td>
* <td>Yes</td> * <td>No</td>
* <td>N/A</td> * <td>Null</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>type</td> * <td>type</td>
@ -91,8 +91,8 @@ public class LegacyNumericRangeQueryBuilder implements QueryBuilder {
@Override @Override
public Query getQuery(Element e) throws ParserException { public Query getQuery(Element e) throws ParserException {
String field = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName"); String field = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName");
String lowerTerm = DOMUtils.getAttributeOrFail(e, "lowerTerm"); final String lowerTerm = DOMUtils.getAttribute(e, "lowerTerm", null);
String upperTerm = DOMUtils.getAttributeOrFail(e, "upperTerm"); final String upperTerm = DOMUtils.getAttribute(e, "upperTerm", null);
boolean lowerInclusive = DOMUtils.getAttribute(e, "includeLower", true); boolean lowerInclusive = DOMUtils.getAttribute(e, "includeLower", true);
boolean upperInclusive = DOMUtils.getAttribute(e, "includeUpper", true); boolean upperInclusive = DOMUtils.getAttribute(e, "includeUpper", true);
int precisionStep = DOMUtils.getAttribute(e, "precisionStep", LegacyNumericUtils.PRECISION_STEP_DEFAULT); int precisionStep = DOMUtils.getAttribute(e, "precisionStep", LegacyNumericUtils.PRECISION_STEP_DEFAULT);
@ -101,20 +101,28 @@ public class LegacyNumericRangeQueryBuilder implements QueryBuilder {
try { try {
Query filter; Query filter;
if (type.equalsIgnoreCase("int")) { if (type.equalsIgnoreCase("int")) {
filter = LegacyNumericRangeQuery.newIntRange(field, precisionStep, Integer filter = LegacyNumericRangeQuery.newIntRange(field, precisionStep,
.valueOf(lowerTerm), Integer.valueOf(upperTerm), lowerInclusive, (lowerTerm == null ? null : Integer.valueOf(lowerTerm)),
(upperTerm == null ? null : Integer.valueOf(upperTerm)),
lowerInclusive,
upperInclusive); upperInclusive);
} else if (type.equalsIgnoreCase("long")) { } else if (type.equalsIgnoreCase("long")) {
filter = LegacyNumericRangeQuery.newLongRange(field, precisionStep, Long filter = LegacyNumericRangeQuery.newLongRange(field, precisionStep,
.valueOf(lowerTerm), Long.valueOf(upperTerm), lowerInclusive, (lowerTerm == null ? null : Long.valueOf(lowerTerm)),
(upperTerm == null ? null : Long.valueOf(upperTerm)),
lowerInclusive,
upperInclusive); upperInclusive);
} else if (type.equalsIgnoreCase("double")) { } else if (type.equalsIgnoreCase("double")) {
filter = LegacyNumericRangeQuery.newDoubleRange(field, precisionStep, Double filter = LegacyNumericRangeQuery.newDoubleRange(field, precisionStep,
.valueOf(lowerTerm), Double.valueOf(upperTerm), lowerInclusive, (lowerTerm == null ? null : Double.valueOf(lowerTerm)),
(upperTerm == null ? null : Double.valueOf(upperTerm)),
lowerInclusive,
upperInclusive); upperInclusive);
} else if (type.equalsIgnoreCase("float")) { } else if (type.equalsIgnoreCase("float")) {
filter = LegacyNumericRangeQuery.newFloatRange(field, precisionStep, Float filter = LegacyNumericRangeQuery.newFloatRange(field, precisionStep,
.valueOf(lowerTerm), Float.valueOf(upperTerm), lowerInclusive, (lowerTerm == null ? null : Float.valueOf(lowerTerm)),
(upperTerm == null ? null : Float.valueOf(upperTerm)),
lowerInclusive,
upperInclusive); upperInclusive);
} else { } else {
throw new ParserException("type attribute must be one of: [long, int, double, float]"); throw new ParserException("type attribute must be one of: [long, int, double, float]");

View File

@ -46,14 +46,14 @@ import org.w3c.dom.Element;
* <tr> * <tr>
* <td>lowerTerm</td> * <td>lowerTerm</td>
* <td>Specified by <tt>type</tt></td> * <td>Specified by <tt>type</tt></td>
* <td>Yes</td> * <td>No</td>
* <td>N/A</td> * <td>Integer.MIN_VALUE Long.MIN_VALUE Float.NEGATIVE_INFINITY Double.NEGATIVE_INFINITY</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>upperTerm</td> * <td>upperTerm</td>
* <td>Specified by <tt>type</tt></td> * <td>Specified by <tt>type</tt></td>
* <td>Yes</td> * <td>No</td>
* <td>N/A</td> * <td>Integer.MAX_VALUE Long.MAX_VALUE Float.POSITIVE_INFINITY Double.POSITIVE_INFINITY</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>type</td> * <td>type</td>
@ -72,19 +72,27 @@ public class PointRangeQueryBuilder implements QueryBuilder {
@Override @Override
public Query getQuery(Element e) throws ParserException { public Query getQuery(Element e) throws ParserException {
String field = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName"); String field = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName");
String lowerTerm = DOMUtils.getAttributeOrFail(e, "lowerTerm"); final String lowerTerm = DOMUtils.getAttribute(e, "lowerTerm", null);
String upperTerm = DOMUtils.getAttributeOrFail(e, "upperTerm"); final String upperTerm = DOMUtils.getAttribute(e, "upperTerm", null);
String type = DOMUtils.getAttribute(e, "type", "int"); String type = DOMUtils.getAttribute(e, "type", "int");
try { try {
if (type.equalsIgnoreCase("int")) { if (type.equalsIgnoreCase("int")) {
return IntPoint.newRangeQuery(field, Integer.valueOf(lowerTerm), Integer.valueOf(upperTerm)); return IntPoint.newRangeQuery(field,
(lowerTerm == null ? Integer.MIN_VALUE : Integer.valueOf(lowerTerm)),
(upperTerm == null ? Integer.MAX_VALUE : Integer.valueOf(upperTerm)));
} else if (type.equalsIgnoreCase("long")) { } else if (type.equalsIgnoreCase("long")) {
return LongPoint.newRangeQuery(field, Long.valueOf(lowerTerm), Long.valueOf(upperTerm)); return LongPoint.newRangeQuery(field,
(lowerTerm == null ? Long.MIN_VALUE : Long.valueOf(lowerTerm)),
(upperTerm == null ? Long.MAX_VALUE : Long.valueOf(upperTerm)));
} else if (type.equalsIgnoreCase("double")) { } else if (type.equalsIgnoreCase("double")) {
return DoublePoint.newRangeQuery(field, Double.valueOf(lowerTerm), Double.valueOf(upperTerm)); return DoublePoint.newRangeQuery(field,
(lowerTerm == null ? Double.NEGATIVE_INFINITY : Double.valueOf(lowerTerm)),
(upperTerm == null ? Double.POSITIVE_INFINITY : Double.valueOf(upperTerm)));
} else if (type.equalsIgnoreCase("float")) { } else if (type.equalsIgnoreCase("float")) {
return FloatPoint.newRangeQuery(field, Float.valueOf(lowerTerm), Float.valueOf(upperTerm)); return FloatPoint.newRangeQuery(field,
(lowerTerm == null ? Float.NEGATIVE_INFINITY : Float.valueOf(lowerTerm)),
(upperTerm == null ? Float.POSITIVE_INFINITY : Float.valueOf(upperTerm)));
} else { } else {
throw new ParserException("type attribute must be one of: [long, int, double, float]"); throw new ParserException("type attribute must be one of: [long, int, double, float]");
} }

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<BooleanQuery fieldName="contents">
<Clause occurs="should">
<TermQuery>merger</TermQuery>
</Clause>
<Clause occurs="mustnot">
<TermQuery >sumitomo</TermQuery>
</Clause>
<Clause occurs="must">
<TermQuery>bank</TermQuery>
</Clause>
<Clause occurs="must">
<LegacyNumericRangeQuery fieldName="date2" upperTerm="19870412"/>
</Clause>
</BooleanQuery>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<BooleanQuery fieldName="contents">
<Clause occurs="should">
<TermQuery>merger</TermQuery>
</Clause>
<Clause occurs="mustnot">
<TermQuery >sumitomo</TermQuery>
</Clause>
<Clause occurs="must">
<TermQuery>bank</TermQuery>
</Clause>
<Clause occurs="must">
<LegacyNumericRangeQuery fieldName="date2"/>
</Clause>
</BooleanQuery>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<BooleanQuery fieldName="contents">
<Clause occurs="should">
<TermQuery>merger</TermQuery>
</Clause>
<Clause occurs="mustnot">
<TermQuery >sumitomo</TermQuery>
</Clause>
<Clause occurs="must">
<TermQuery>bank</TermQuery>
</Clause>
<Clause occurs="must">
<LegacyNumericRangeQuery fieldName="date2" lowerTerm="19870409"/>
</Clause>
</BooleanQuery>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<BooleanQuery fieldName="contents">
<Clause occurs="should">
<TermQuery>merger</TermQuery>
</Clause>
<Clause occurs="mustnot">
<TermQuery >sumitomo</TermQuery>
</Clause>
<Clause occurs="must">
<TermQuery>bank</TermQuery>
</Clause>
<Clause occurs="must">
<PointRangeQuery fieldName="date3" upperTerm="19870412"/>
</Clause>
</BooleanQuery>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<BooleanQuery fieldName="contents">
<Clause occurs="should">
<TermQuery>merger</TermQuery>
</Clause>
<Clause occurs="mustnot">
<TermQuery >sumitomo</TermQuery>
</Clause>
<Clause occurs="must">
<TermQuery>bank</TermQuery>
</Clause>
<Clause occurs="must">
<PointRangeQuery fieldName="date3"/>
</Clause>
</BooleanQuery>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<BooleanQuery fieldName="contents">
<Clause occurs="should">
<TermQuery>merger</TermQuery>
</Clause>
<Clause occurs="mustnot">
<TermQuery >sumitomo</TermQuery>
</Clause>
<Clause occurs="must">
<TermQuery>bank</TermQuery>
</Clause>
<Clause occurs="must">
<PointRangeQuery fieldName="date3" lowerTerm="19870409"/>
</Clause>
</BooleanQuery>

View File

@ -132,12 +132,42 @@ public class TestCoreParser extends LuceneTestCase {
Query q = parse("LegacyNumericRangeQuery.xml"); Query q = parse("LegacyNumericRangeQuery.xml");
dumpResults("LegacyNumericRangeQuery", q, 5); dumpResults("LegacyNumericRangeQuery", q, 5);
} }
public void testNumericRangeQueryXMLWithoutLowerTerm() throws ParserException, IOException {
Query q = parse("LegacyNumericRangeQueryWithoutLowerTerm.xml");
dumpResults("LegacyNumericRangeQueryWithoutLowerTerm", q, 5);
}
public void testNumericRangeQueryXMLWithoutUpperTerm() throws ParserException, IOException {
Query q = parse("LegacyNumericRangeQueryWithoutUpperTerm.xml");
dumpResults("LegacyNumericRangeQueryWithoutUpperTerm", q, 5);
}
public void testNumericRangeQueryXMLWithoutRange() throws ParserException, IOException {
Query q = parse("LegacyNumericRangeQueryWithoutRange.xml");
dumpResults("LegacyNumericRangeQueryWithoutRange", q, 5);
}
public void testPointRangeQuery() throws ParserException, IOException { public void testPointRangeQuery() throws ParserException, IOException {
Query q = parse("PointRangeQuery.xml"); Query q = parse("PointRangeQuery.xml");
dumpResults("PointRangeQuery", q, 5); dumpResults("PointRangeQuery", q, 5);
} }
public void testPointRangeQueryWithoutLowerTerm() throws ParserException, IOException {
Query q = parse("PointRangeQueryWithoutLowerTerm.xml");
dumpResults("PointRangeQueryWithoutLowerTerm", q, 5);
}
public void testPointRangeQueryWithoutUpperTerm() throws ParserException, IOException {
Query q = parse("PointRangeQueryWithoutUpperTerm.xml");
dumpResults("PointRangeQueryWithoutUpperTerm", q, 5);
}
public void testPointRangeQueryWithoutRange() throws ParserException, IOException {
Query q = parse("PointRangeQueryWithoutRange.xml");
dumpResults("PointRangeQueryWithoutRange", q, 5);
}
//================= Helper methods =================================== //================= Helper methods ===================================
protected String defaultField() { protected String defaultField() {