Skip to content

Commit a0e4f98

Browse files
committed
address review comments
1 parent 4fb0d17 commit a0e4f98

File tree

2 files changed

+56
-16
lines changed

2 files changed

+56
-16
lines changed

parquet-column/src/main/java/org/apache/parquet/column/statistics/geospatial/BoundingBox.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -314,17 +314,14 @@ public void update(Geometry geometry) {
314314
*/
315315
private void updateBounds(double minX, double maxX, double minY, double maxY) {
316316
if (!Double.isNaN(minX) && !Double.isNaN(maxX)) {
317-
double newXMin = Math.min(xMin, minX);
318-
double newXMax = Math.max(xMax, maxX);
319-
320317
// Check if the update would create a wraparound condition
321318
// This should never happen with standard JTS geometry operations
322-
if (isWraparound(newXMin, newXMax)) {
323-
throw new ShouldNeverHappenException("Wraparound X is not supported by BoundingBox.update()");
319+
if (isWraparound(minX, maxX) || isWraparound(xMin, xMax)) {
320+
throw new ShouldNeverHappenException("Wraparound bounding boxes are not yet supported");
324321
}
325322

326-
xMin = newXMin;
327-
xMax = newXMax;
323+
xMin = Math.min(xMin, minX);
324+
xMax = Math.max(xMax, maxX);
328325
}
329326

330327
if (!Double.isNaN(minY) && !Double.isNaN(maxY)) {
@@ -353,7 +350,7 @@ public void reset() {
353350
* The Parquet specification allows X bounds to be "wraparound" to allow for
354351
* more compact bounding boxes when a geometry happens to include components
355352
* on both sides of the antimeridian (e.g., the nation of Fiji). This function
356-
* checks for that case (see GeoStatistics::lower_bound/upper_bound for more details).
353+
* checks for that case.
357354
*/
358355
public static boolean isWraparound(double xmin, double xmax) {
359356
return !Double.isInfinite(xmin - xmax) && xmin > xmax;

parquet-column/src/test/java/org/apache/parquet/column/statistics/geospatial/TestBoundingBox.java

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -530,34 +530,34 @@ public void testLineStringWithPartialNaNCoordinates() {
530530

531531
/**
532532
* Tests the end-to-end case for updating and merging bounding boxes with mixed valid and NaN coordinates.
533-
*
533+
* <p>
534534
* Scenario - Parquet file with multiple row groups:
535535
* file-level bbox: [1, 9, 100, 900]
536-
*
536+
* <p>
537537
* Row group 1: [1, 2, 100, 100]
538538
* - POINT (1, 100)
539539
* - POINT (2, NaN)
540-
*
540+
* <p>
541541
* Row group 2: [3, 3, 300, 300]
542542
* - POINT (3, 300)
543543
* - POINT (NaN, NaN)
544-
*
544+
* <p>
545545
* Row group 3: no valid bbox
546546
* - POINT (5, NaN)
547547
* - POINT (6, NaN)
548-
*
548+
* <p>
549549
* Row group 4: [7, 8, 700, 800]
550550
* - POINT (7, 700)
551551
* - POINT (8, 800)
552-
*
552+
* <p>
553553
* Row group 5: no valid bbox
554554
* - POINT (NaN, NaN)
555555
* - POINT (NaN, NaN)
556-
*
556+
* <p>
557557
* Row group 6: [9, 9, 900, 900]
558558
* - POINT (9, 900)
559559
* - LINESTRING EMPTY
560-
*
560+
* <p>
561561
* The test verifies that:
562562
* 1. Individual row group bounding boxes correctly handle NaN coordinates
563563
* 2. The merge operation correctly combines valid bounding boxes and ignores invalid ones
@@ -688,22 +688,33 @@ public void testIsXValidAndIsYValid() {
688688
BoundingBox validBox = new BoundingBox(1, 2, 3, 4, 5, 6, 7, 8);
689689
Assert.assertTrue(validBox.isXValid());
690690
Assert.assertTrue(validBox.isYValid());
691+
Assert.assertTrue(validBox.isXYValid());
692+
Assert.assertTrue(validBox.isZValid());
693+
Assert.assertTrue(validBox.isMValid());
691694

692695
// Test with invalid X (NaN)
693696
BoundingBox invalidXBox = new BoundingBox(Double.NaN, 2, 3, 4, 5, 6, 7, 8);
694697
Assert.assertFalse(invalidXBox.isXValid());
695698
Assert.assertTrue(invalidXBox.isYValid());
699+
Assert.assertFalse(invalidXBox.isXYValid());
700+
Assert.assertTrue(invalidXBox.isZValid());
701+
Assert.assertTrue(invalidXBox.isMValid());
696702

697703
// Test with invalid Y (NaN)
698704
BoundingBox invalidYBox = new BoundingBox(1, 2, Double.NaN, 4, 5, 6, 7, 8);
699705
Assert.assertTrue(invalidYBox.isXValid());
700706
Assert.assertFalse(invalidYBox.isYValid());
707+
Assert.assertFalse(invalidXBox.isXYValid());
708+
Assert.assertTrue(invalidXBox.isZValid());
709+
Assert.assertTrue(invalidXBox.isMValid());
701710

702711
// Test with both X and Y invalid
703712
BoundingBox invalidXYBox = new BoundingBox(Double.NaN, Double.NaN, Double.NaN, Double.NaN, 5, 6, 7, 8);
704713
Assert.assertFalse(invalidXYBox.isXValid());
705714
Assert.assertFalse(invalidXYBox.isYValid());
706715
Assert.assertFalse(invalidXYBox.isXYValid());
716+
Assert.assertTrue(invalidXBox.isZValid());
717+
Assert.assertTrue(invalidXBox.isMValid());
707718
}
708719

709720
@Test
@@ -755,6 +766,16 @@ public void testIsXWraparound() {
755766
// Test static method directly
756767
Assert.assertTrue(BoundingBox.isWraparound(180, -180));
757768
Assert.assertFalse(BoundingBox.isWraparound(-180, 180));
769+
770+
// Test with infinity values
771+
Assert.assertFalse(BoundingBox.isWraparound(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY));
772+
Assert.assertFalse(BoundingBox.isWraparound(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
773+
Assert.assertFalse(BoundingBox.isWraparound(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY));
774+
Assert.assertFalse(BoundingBox.isWraparound(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY));
775+
776+
// Check edge cases
777+
Assert.assertFalse(BoundingBox.isWraparound(0.0, Double.POSITIVE_INFINITY));
778+
Assert.assertFalse(BoundingBox.isWraparound(Double.NEGATIVE_INFINITY, 0.0));
758779
}
759780

760781
@Test
@@ -780,4 +801,26 @@ public void testWraparoundHandlingInMerge() {
780801
Assert.assertEquals(0.0, normalBox.getYMin(), 0.0);
781802
Assert.assertEquals(15.0, normalBox.getYMax(), 0.0);
782803
}
804+
805+
@Test
806+
public void testWraparoundBoxMergingNormalBox() {
807+
// Create a normal bounding box
808+
BoundingBox normalBox = new BoundingBox(0, 10, 0, 10, 0, 0, 0, 0);
809+
810+
// Create a wraparound bounding box (xMin > xMax)
811+
BoundingBox wraparoundBox = new BoundingBox(170, -170, 5, 15, 0, 0, 0, 0);
812+
813+
// Merge the normal box into the wraparound box
814+
wraparoundBox.merge(normalBox);
815+
816+
// After merging, X dimension should be marked as invalid (NaN)
817+
// because we don't support merging wraparound bounds
818+
Assert.assertFalse(wraparoundBox.isValid());
819+
Assert.assertTrue(Double.isNaN(wraparoundBox.getXMin()));
820+
Assert.assertTrue(Double.isNaN(wraparoundBox.getXMax()));
821+
822+
// Y dimension should be properly merged
823+
Assert.assertEquals(0.0, wraparoundBox.getYMin(), 0.0);
824+
Assert.assertEquals(15.0, wraparoundBox.getYMax(), 0.0);
825+
}
783826
}

0 commit comments

Comments
 (0)