You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by sz...@apache.org on 2026/07/11 06:53:28 UTC

(iceberg) branch main updated: Core: Test geometry and geography metrics keep counts without bounds (#17147)

This is an automated email from the ASF dual-hosted git repository.

szehon-ho pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg.git


The following commit(s) were added to refs/heads/main by this push:
     new d99b0eefab Core: Test geometry and geography metrics keep counts without bounds (#17147)
d99b0eefab is described below

commit d99b0eefab6a9459e65a77448de914c61a89fadd
Author: Xin Huang <42...@users.noreply.github.com>
AuthorDate: Fri Jul 10 23:53:21 2026 -0700

    Core: Test geometry and geography metrics keep counts without bounds (#17147)
---
 .../test/java/org/apache/iceberg/TestMetrics.java  | 44 ++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/core/src/test/java/org/apache/iceberg/TestMetrics.java b/core/src/test/java/org/apache/iceberg/TestMetrics.java
index feffc18477..095feb2938 100644
--- a/core/src/test/java/org/apache/iceberg/TestMetrics.java
+++ b/core/src/test/java/org/apache/iceberg/TestMetrics.java
@@ -29,6 +29,7 @@ import java.io.File;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.nio.CharBuffer;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Path;
@@ -257,6 +258,37 @@ public abstract class TestMetrics {
     }
   }
 
+  @TestTemplate
+  public void testMetricsForGeospatialTypes() throws IOException {
+    // Geometry and geography are only written by the Parquet path; other formats do not support
+    // the geo types yet.
+    assumeThat(fileFormat()).isEqualTo(FileFormat.PARQUET);
+
+    Schema schema =
+        new Schema(
+            required(1, "id", LongType.get()),
+            optional(2, "geom", Types.GeometryType.crs84()),
+            optional(3, "geog", Types.GeographyType.crs84()));
+
+    Record first = GenericRecord.create(schema);
+    first.setField("id", 1L);
+    first.setField("geom", wkbPoint(30, 10));
+    first.setField("geog", wkbPoint(-5, 40));
+    Record second = GenericRecord.create(schema);
+    second.setField("id", 2L);
+    // both geo columns are left null
+
+    Metrics metrics = getMetrics(schema, first, second);
+    assertThat(metrics.recordCount()).isEqualTo(2L);
+
+    // geometry and geography keep value/null counts but no bounds: lexicographic WKB min/max is not
+    // meaningful, so bounds are intentionally skipped (spatial bounds are a separate follow-up).
+    assertCounts(2, 2L, 1L, metrics);
+    assertBounds(2, Types.GeometryType.crs84(), null, null, metrics);
+    assertCounts(3, 2L, 1L, metrics);
+    assertBounds(3, Types.GeographyType.crs84(), null, null, metrics);
+  }
+
   @TestTemplate
   public void testMetricsForDecimals() throws IOException {
     Schema schema =
@@ -761,6 +793,18 @@ public abstract class TestMetrics {
     assertBounds(5, LongType.get(), Long.MAX_VALUE, Long.MAX_VALUE, metrics);
   }
 
+  private static ByteBuffer wkbPoint(double xCoord, double yCoord) {
+    // little-endian WKB encoding of a point
+    return ByteBuffer.wrap(
+        ByteBuffer.allocate(21)
+            .order(ByteOrder.LITTLE_ENDIAN)
+            .put((byte) 1) // byte order: little endian
+            .putInt(1) // WKB geometry type: Point
+            .putDouble(xCoord)
+            .putDouble(yCoord)
+            .array());
+  }
+
   protected void assertCounts(int fieldId, Long valueCount, Long nullValueCount, Metrics metrics) {
     assertCounts(fieldId, valueCount, nullValueCount, null, metrics);
   }