diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index c16c0321367..002eafc2493 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -109,6 +109,9 @@ Bug Fixes * LUCENE-7798: Add .equals and .hashCode to ToParentBlockJoinSortField (Mikhail Khludnev) +* LUCENE-7814: DateRangePrefixTree (in spatial-extras ) had edge-case bugs for + years >= 292,000,000. (David Smiley) + Improvements * LUCENE-7782: OfflineSorter now passes the total number of items it diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTree.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTree.java index 4d3ef3b3c1d..cc47358c627 100644 --- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTree.java +++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTree.java @@ -92,7 +92,7 @@ public class DateRangePrefixTree extends NumberRangePrefixTree { private static final int YEAR_LEVEL = 3; //how many million years are there? - private static final int NUM_MYEARS = 585;// we assert how this was computed in the constructor + private static final int NUM_MYEARS = 586;// we assert how this was computed in the constructor /** An instanced based on {@link Calendar#getInstance(TimeZone, Locale)} with UTC and Locale.Root. This * will (always?) be a {@link GregorianCalendar} with a so-called "Gregorian Change Date" of 1582. @@ -142,9 +142,9 @@ public class DateRangePrefixTree extends NumberRangePrefixTree { BC_YEARS = BC_FIRSTYEAR - BC_LASTYEAR + 1; AD_FIRSTYEAR = MAXCAL.getActualMinimum(Calendar.YEAR); // 1 AD_LASTYEAR = MAXCAL.getActualMaximum(Calendar.YEAR); - AD_YEAR_BASE = (((BC_YEARS-1) / 1000_000)+1) * 1000_000; + AD_YEAR_BASE = (((BC_YEARS-1) / 1000_000)+1) * 1000_000; // align year 0 at an even # of million years assert BC_LASTYEAR == 1 && AD_FIRSTYEAR == 1; - assert NUM_MYEARS == (AD_YEAR_BASE + AD_LASTYEAR) / 1000_000; + assert NUM_MYEARS == (AD_YEAR_BASE + AD_LASTYEAR) / 1000_000 + 1; maxLV = toShape((Calendar)MAXCAL.clone()); minLV = toShape((Calendar)MINCAL.clone()); @@ -165,7 +165,7 @@ public class DateRangePrefixTree extends NumberRangePrefixTree { int cmp = comparePrefix(lv, maxLV); assert cmp <= 0; if (cmp == 0)//edge case (literally!) - return maxLV.getValAtLevel(lv.getLevel()+1); + return maxLV.getValAtLevel(lv.getLevel()+1) + 1; // if using GregorianCalendar and we're after the "Gregorian change date" then we'll compute // the sub-cells ourselves more efficiently without the need to construct a Calendar. diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/DateNRStrategyTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/DateNRStrategyTest.java index 9b93aac04e0..77c25298b67 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/DateNRStrategyTest.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/DateNRStrategyTest.java @@ -103,6 +103,15 @@ public class DateNRStrategyTest extends RandomSpatialOpStrategyTestCase { tree.parseShape("[2014-04 TO 2014-04-01T02]"), true); } + @Test + public void testLastMillionYearPeriod() throws Exception { + testOperation( + tree.parseShape("+292220922-05-17T18:01:57.572"), // a year in the last million year period (>=292M) + SpatialOperation.Intersects, + tree.parseShape("[1970 TO *]"), true + ); + } + @Override protected Shape randomIndexedShape() { Calendar cal1 = randomCalendar();