Copilot commented on code in PR #6581:
URL: https://github.com/apache/hive/pull/6581#discussion_r3542670549


##########
ql/src/java/org/apache/hadoop/hive/ql/udf/esri/ST_PointFromWKB.java:
##########
@@ -55,17 +52,11 @@ public BytesWritable evaluate(BytesWritable wkb) throws 
UDFArgumentException {
   public BytesWritable evaluate(BytesWritable wkb, int wkid) throws 
UDFArgumentException {
 
     try {
-      SpatialReference spatialReference = null;
-      if (wkid != GeometryUtils.WKID_UNKNOWN) {
-        spatialReference = SpatialReference.create(wkid);
-      }
-      byte[] byteArr = wkb.getBytes();
-      ByteBuffer byteBuf = ByteBuffer.allocate(byteArr.length);
-      byteBuf.put(byteArr);
-      OGCGeometry ogcObj = OGCGeometry.fromBinary(byteBuf);
-      ogcObj.setSpatialReference(spatialReference);
-      if (ogcObj.geometryType().equals("Point")) {
-        return GeometryUtils.geometryToEsriShapeBytesWritable(ogcObj);
+      byte[] bytes = wkb.getBytes();
+      Geometry geom = GeometryUtils.wkbReader().read(bytes);

Review Comment:
   BytesWritable#getBytes() returns the backing array which may be larger than 
the valid payload; passing it directly to WKBReader can include trailing 
garbage bytes and cause parse failures. Use getLength() to bound/copy the byte 
array before parsing.



##########
ql/src/java/org/apache/hadoop/hive/ql/udf/esri/ST_LineFromWKB.java:
##########
@@ -55,17 +52,11 @@ public BytesWritable evaluate(BytesWritable wkb) throws 
UDFArgumentException {
   public BytesWritable evaluate(BytesWritable wkb, int wkid) throws 
UDFArgumentException {
 
     try {
-      SpatialReference spatialReference = null;
-      if (wkid != GeometryUtils.WKID_UNKNOWN) {
-        spatialReference = SpatialReference.create(wkid);
-      }
-      byte[] byteArr = wkb.getBytes();
-      ByteBuffer byteBuf = ByteBuffer.allocate(byteArr.length);
-      byteBuf.put(byteArr);
-      OGCGeometry ogcObj = OGCGeometry.fromBinary(byteBuf);
-      ogcObj.setSpatialReference(spatialReference);
-      if (ogcObj.geometryType().equals("LineString")) {
-        return GeometryUtils.geometryToEsriShapeBytesWritable(ogcObj);
+      byte[] bytes = wkb.getBytes();
+      Geometry geom = GeometryUtils.wkbReader().read(bytes);

Review Comment:
   BytesWritable#getBytes() returns the backing array which may include extra 
unused bytes; passing it directly to WKBReader can corrupt parsing. Bound the 
input using getLength() (or wrap with offset/length) before reading.



##########
ql/src/java/org/apache/hadoop/hive/ql/udf/esri/ST_GeomFromWKB.java:
##########
@@ -76,16 +73,12 @@ public BytesWritable evaluate(BytesWritable wkb) throws 
UDFArgumentException {
   public BytesWritable evaluate(BytesWritable wkb, int wkid) throws 
UDFArgumentException {
 
     try {
-      SpatialReference spatialReference = null;
+      byte[] byteArr = wkb.getBytes();
+      Geometry geom = GeometryUtils.wkbReader().read(byteArr);

Review Comment:
   BytesWritable#getBytes() returns the backing array; using it directly can 
include bytes beyond wkb.getLength() and break WKB parsing. Copy/slice the 
array to the correct length first.



##########
ql/src/java/org/apache/hadoop/hive/ql/udf/esri/ST_Is3D.java:
##########
@@ -61,13 +62,14 @@ public BooleanWritable evaluate(BytesWritable geomref) {
       return null;
     }
 
-    OGCGeometry ogcGeometry = GeometryUtils.geometryFromEsriShape(geomref);
-    if (ogcGeometry == null) {
+    Geometry geom = GeometryUtils.geometryFromEsriShape(geomref);
+    if (geom == null) {
       LogUtils.Log_ArgumentsNull(LOG);
       return null;
     }
 
-    resultBoolean.set(ogcGeometry.is3D());
+    Coordinate coord = geom.getCoordinate();
+    resultBoolean.set(coord != null && !Double.isNaN(coord.getZ()));

Review Comment:
   ST_Is3D currently checks only geom.getCoordinate().getZ(), which can be 
misleading for GeometryCollections and also doesn't mirror the repo's dimension 
detection logic that guards against NaN Z. Prefer using 
GeometryUtils.getOrdinates(geom) to detect whether Z is actually present.



##########
ql/src/java/org/apache/hadoop/hive/ql/udf/esri/ST_GeomFromShape.java:
##########
@@ -40,29 +41,14 @@ public BytesWritable evaluate(BytesWritable shape) throws 
UDFArgumentException {
 
   public BytesWritable evaluate(BytesWritable shape, int wkid) throws 
UDFArgumentException {
     try {
-      Geometry geometry = 
GeometryEngine.geometryFromEsriShape(shape.getBytes(), Geometry.Type.Unknown);
-      switch (geometry.getType()) {
-      case Point:
-        return GeometryUtils.geometryToEsriShapeBytesWritable(geometry, wkid, 
OGCType.ST_POINT);
-
-      case MultiPoint:
-        return GeometryUtils.geometryToEsriShapeBytesWritable(geometry, wkid, 
OGCType.ST_MULTIPOINT);
-
-      case Line:
-        return GeometryUtils.geometryToEsriShapeBytesWritable(geometry, wkid, 
OGCType.ST_LINESTRING);
-
-      case Polyline:
-        return GeometryUtils.geometryToEsriShapeBytesWritable(geometry, wkid, 
OGCType.ST_MULTILINESTRING);
-
-      case Envelope:
-        return GeometryUtils.geometryToEsriShapeBytesWritable(geometry, wkid, 
OGCType.ST_POLYGON);
-
-      case Polygon:
-        return GeometryUtils.geometryToEsriShapeBytesWritable(geometry, wkid, 
OGCType.ST_MULTIPOLYGON);
-
-      default:
-        return GeometryUtils.geometryToEsriShapeBytesWritable(geometry, wkid, 
OGCType.UNKNOWN);
+      byte[] bytes = shape.getBytes();
+      ByteBuffer shapeBuffer = 
ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);

Review Comment:
   BytesWritable#getBytes() returns the backing array; wrapping the whole array 
can include bytes beyond shape.getLength() and confuse Esri-shape parsing. Wrap 
only the valid slice using offset/length.



##########
ql/src/java/org/apache/hadoop/hive/ql/udf/esri/ST_IsMeasured.java:
##########
@@ -61,13 +62,14 @@ public BooleanWritable evaluate(BytesWritable geomref) {
       return null;
     }
 
-    OGCGeometry ogcGeometry = GeometryUtils.geometryFromEsriShape(geomref);
-    if (ogcGeometry == null) {
+    Geometry geom = GeometryUtils.geometryFromEsriShape(geomref);
+    if (geom == null) {
       LogUtils.Log_ArgumentsNull(LOG);
       return null;
     }
 
-    resultBoolean.set(ogcGeometry.isMeasured());
+    Coordinate coord = geom.getCoordinate();
+    resultBoolean.set(coord != null && !Double.isNaN(coord.getM()));

Review Comment:
   ST_IsMeasured currently checks only geom.getCoordinate().getM(), which can 
be incorrect for multi-geometries and doesn't match the codebase's ordinate 
detection helper. Use GeometryUtils.getOrdinates(geom) so measured-ness is 
detected consistently.



##########
serde/src/java/org/apache/hadoop/hive/serde2/esriJson/serializer/GeometryJsonSerializer.java:
##########
@@ -17,19 +17,32 @@
  */
 package org.apache.hadoop.hive.serde2.esriJson.serializer;
 
-import com.esri.core.geometry.Geometry;
 import com.esri.core.geometry.GeometryEngine;
+import com.esri.core.geometry.ogc.OGCGeometry;
 import com.fasterxml.jackson.core.JsonGenerator;
 import com.fasterxml.jackson.databind.JsonSerializer;
 import com.fasterxml.jackson.databind.SerializerProvider;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.io.WKBWriter;
 
 import java.io.IOException;
 
+/**
+ * Serializes a JTS Geometry to Esri JSON format.
+ * Converts JTS -> ESRI via WKB round-trip, then uses 
GeometryEngine.geometryToJson().
+ */
 public class GeometryJsonSerializer extends JsonSerializer<Geometry> {
 
   @Override
   public void serialize(Geometry geometry, JsonGenerator jsonGenerator, 
SerializerProvider arg2) throws IOException {
-
-    jsonGenerator.writeRawValue(GeometryEngine.geometryToJson(null, geometry));
+    try {
+      byte[] wkb = new WKBWriter().write(geometry);
+      OGCGeometry ogcGeom = 
OGCGeometry.fromBinary(java.nio.ByteBuffer.wrap(wkb));
+      com.esri.core.geometry.Geometry esriGeom = ogcGeom.getEsriGeometry();
+      int wkid = geometry.getSRID();
+      jsonGenerator.writeRawValue(GeometryEngine.geometryToJson(wkid, 
esriGeom));
+    } catch (Exception e) {
+      jsonGenerator.writeNull();
+    }

Review Comment:
   This serializer swallows all exceptions and writes JSON null, which can 
silently drop geometries during serialization and make failures hard to 
diagnose. Prefer failing fast by surfacing the error as an IOException (or at 
least logging it) so callers/test output show the root cause.



##########
ql/src/java/org/apache/hadoop/hive/ql/udf/esri/ST_MLineFromWKB.java:
##########
@@ -55,18 +52,12 @@ public BytesWritable evaluate(BytesWritable wkb) throws 
UDFArgumentException {
   public BytesWritable evaluate(BytesWritable wkb, int wkid) throws 
UDFArgumentException {
 
     try {
-      SpatialReference spatialReference = null;
-      if (wkid != GeometryUtils.WKID_UNKNOWN) {
-        spatialReference = SpatialReference.create(wkid);
-      }
-      byte[] byteArr = wkb.getBytes();
-      ByteBuffer byteBuf = ByteBuffer.allocate(byteArr.length);
-      byteBuf.put(byteArr);
-      OGCGeometry ogcObj = OGCGeometry.fromBinary(byteBuf);
-      ogcObj.setSpatialReference(spatialReference);
-      String gType = ogcObj.geometryType();
+      byte[] bytes = wkb.getBytes();
+      Geometry geom = GeometryUtils.wkbReader().read(bytes);

Review Comment:
   BytesWritable#getBytes() may include unused trailing bytes; pass only the 
valid slice (getLength()) to WKBReader to avoid parse failures.



##########
ql/src/java/org/apache/hadoop/hive/ql/io/esriJson/EsriFeatureClass.java:
##########
@@ -39,14 +43,19 @@ public class EsriFeatureClass {
   public Map<String, Object> fieldAliases;
 
   /**
-   * Esri geometry type (Polygon, Point, ...)
+   * Esri geometry type string (e.g. "esriGeometryPoint", 
"esriGeometryPolygon").
    */
-  public Geometry.Type geometryType;
+  @JsonDeserialize(using = GeometryTypeJsonDeserializer.class)
+  @JsonSerialize(using = GeometryTypeJsonSerializer.class)
+  public String geometryType;
 
   /**
-   * Spatial reference for the feature class (null, if undefined)
+   * Spatial reference WKID for the feature class (0 if undefined).
+   * The JSON form is {"wkid": N}; deserialized to a plain int.
    */
-  public SpatialReference spatialReference;
+  @JsonDeserialize(using = SpatialReferenceJsonDeserializer.class)
+  @JsonSerialize(using = SpatialReferenceJsonSerializer.class)
+  public int spatialReference;

Review Comment:
   With spatialReference as a primitive int defaulting to 0, Jackson will 
always serialize it, producing a spatialReference object with wkid=0. That 
differs from EsriJsonConverter's convention (wkid==0 means omit 
spatialReference) and can produce non-canonical Esri JSON. Consider excluding 
default 0 from serialization.



##########
ql/src/java/org/apache/hadoop/hive/ql/udf/esri/ST_MPointFromWKB.java:
##########
@@ -55,20 +52,14 @@ public BytesWritable evaluate(BytesWritable wkb) throws 
UDFArgumentException {
   public BytesWritable evaluate(BytesWritable wkb, int wkid) throws 
UDFArgumentException {
 
     try {
-      SpatialReference spatialReference = null;
-      if (wkid != GeometryUtils.WKID_UNKNOWN) {
-        spatialReference = SpatialReference.create(wkid);
-      }
-      byte[] byteArr = wkb.getBytes();
-      ByteBuffer byteBuf = ByteBuffer.allocate(byteArr.length);
-      byteBuf.put(byteArr);
-      OGCGeometry ogcObj = OGCGeometry.fromBinary(byteBuf);
-      ogcObj.setSpatialReference(spatialReference);
-      String gType = ogcObj.geometryType();
+      byte[] bytes = wkb.getBytes();
+      Geometry geom = GeometryUtils.wkbReader().read(bytes);

Review Comment:
   BytesWritable#getBytes() returns the backing array, not necessarily sized to 
the payload; using it directly can feed extra bytes into WKBReader. Copy/slice 
using wkb.getLength() first.



##########
ql/src/java/org/apache/hadoop/hive/ql/udf/esri/ST_MPolyFromWKB.java:
##########
@@ -55,18 +52,12 @@ public BytesWritable evaluate(BytesWritable wkb) throws 
UDFArgumentException {
   public BytesWritable evaluate(BytesWritable wkb, int wkid) throws 
UDFArgumentException {
 
     try {
-      SpatialReference spatialReference = null;
-      if (wkid != GeometryUtils.WKID_UNKNOWN) {
-        spatialReference = SpatialReference.create(wkid);
-      }
-      byte[] byteArr = wkb.getBytes();
-      ByteBuffer byteBuf = ByteBuffer.allocate(byteArr.length);
-      byteBuf.put(byteArr);
-      OGCGeometry ogcObj = OGCGeometry.fromBinary(byteBuf);
-      ogcObj.setSpatialReference(spatialReference);
-      String gType = ogcObj.geometryType();
+      byte[] bytes = wkb.getBytes();
+      Geometry geom = GeometryUtils.wkbReader().read(bytes);

Review Comment:
   BytesWritable#getBytes() may include bytes beyond the valid payload length; 
pass only the first wkb.getLength() bytes to WKBReader to avoid corrupted 
parses.



##########
ql/src/java/org/apache/hadoop/hive/ql/udf/esri/ST_PolyFromWKB.java:
##########
@@ -55,17 +52,11 @@ public BytesWritable evaluate(BytesWritable wkb) throws 
UDFArgumentException {
   public BytesWritable evaluate(BytesWritable wkb, int wkid) throws 
UDFArgumentException {
 
     try {
-      SpatialReference spatialReference = null;
-      if (wkid != GeometryUtils.WKID_UNKNOWN) {
-        spatialReference = SpatialReference.create(wkid);
-      }
-      byte[] byteArr = wkb.getBytes();
-      ByteBuffer byteBuf = ByteBuffer.allocate(byteArr.length);
-      byteBuf.put(byteArr);
-      OGCGeometry ogcObj = OGCGeometry.fromBinary(byteBuf);
-      ogcObj.setSpatialReference(spatialReference);
-      if (ogcObj.geometryType().equals("Polygon")) {
-        return GeometryUtils.geometryToEsriShapeBytesWritable(ogcObj);
+      byte[] bytes = wkb.getBytes();
+      Geometry geom = GeometryUtils.wkbReader().read(bytes);

Review Comment:
   BytesWritable#getBytes() returns the backing buffer which can be larger than 
wkb.getLength(); WKBReader should only see the valid portion to avoid parse 
errors.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to