You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by bo...@apache.org on 2026/07/31 11:59:23 UTC

(impala) 02/02: IMPALA-15193: [addendum] ST_Disjoint Incorrect Results Workaround

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

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git

commit f0d6958ff10de4a526e5b28b9b6411d452d5a17b
Author: jasonmfehr <jf...@cloudera.com>
AuthorDate: Thu Jul 30 15:02:04 2026 -0700

    IMPALA-15193: [addendum] ST_Disjoint Incorrect Results Workaround
    
    Workaround of a bug in the ST_Disjoint built-in UDF caused by a bug
    in the underpinning esri-geometry-api library. When comparing two
    geometries to determine if they are disjoint where the first
    geometry is either a LineString or a MultiLineString and the second
    geometry is a MultiLineString, then ST_Disjoint incorrectly returns
    false when the first geometry is within the envelope of the second.
    
    The first patch for this issue fixed the ST_Intersects function.
    Since the underlying bug is in the disjoint predicate implementation
    of the esri-geometry-api library, the workaround must also be
    applied to the ST_Disjoint function implementation.
    
    Tested via the addition of new query tests with the test results
    double checked in postgis.
    
    Assisted-by: Github Copilot (GPT-5.3-Codex)
    Change-Id: I66c23c6db1140add91d86dbaeaec9884bcb6a831
    Reviewed-on: http://gerrit.cloudera.org:8080/24648
    Reviewed-by: Csaba Ringhofer <cs...@cloudera.com>
    Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
 .../impala/hive/geospatial/esri/ST_Disjoint.java   | 41 ++++++++++++++++++++++
 .../queries/QueryTest/geospatial-esri-extra.test   | 30 +++++++++++++++-
 2 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/java/hive-geospatial-functions/src/main/java/org/apache/impala/hive/geospatial/esri/ST_Disjoint.java b/java/hive-geospatial-functions/src/main/java/org/apache/impala/hive/geospatial/esri/ST_Disjoint.java
index fa4d9152f..befc166ff 100644
--- a/java/hive-geospatial-functions/src/main/java/org/apache/impala/hive/geospatial/esri/ST_Disjoint.java
+++ b/java/hive-geospatial-functions/src/main/java/org/apache/impala/hive/geospatial/esri/ST_Disjoint.java
@@ -19,6 +19,11 @@ package org.apache.impala.hive.geospatial.esri;
 
 import com.esri.core.geometry.OperatorDisjoint;
 import com.esri.core.geometry.OperatorSimpleRelation;
+import com.esri.core.geometry.SpatialReference;
+import com.esri.core.geometry.ogc.OGCGeometry;
+import com.esri.core.geometry.ogc.OGCLineString;
+import com.esri.core.geometry.ogc.OGCMultiLineString;
+
 import org.apache.hadoop.hive.ql.exec.Description;
 
 @Description(name = "ST_Disjoint",
@@ -38,4 +43,40 @@ public class ST_Disjoint extends ST_GeometryRelational {
   public String getDisplayString(String[] args) {
     return String.format("returns true if %s and %s are disjoint", args[0], args[1]);
   }
+
+  @Override
+  protected Object execEvaluate(OGCGeometry geom1, OGCGeometry geom2,
+      SpatialReference sr) {
+    // IMPALA-15193: Workaround for an underlying issue in the ESRI geometry-api-java
+    // dependency. This issue causes ST_Intersects to incorrectly return true when
+    // geometry 2 is a MultiLineString and geometry 1 is either a LineString or a
+    // MultiLineString.
+    if (geom2 instanceof OGCMultiLineString) {
+      if (geom1 instanceof OGCLineString) {
+        OGCMultiLineString geom2MLS = (OGCMultiLineString) geom2;
+        for (int i = 0; i < geom2MLS.numGeometries(); i++) {
+          if (! (Boolean) super.execEvaluate(geom1, geom2MLS.geometryN(i), sr)) {
+            return false;
+          }
+        }
+
+        return true;
+      } else if(geom1 instanceof OGCMultiLineString) {
+        OGCMultiLineString geom1MLS = (OGCMultiLineString) geom1;
+        OGCMultiLineString geom2MLS = (OGCMultiLineString) geom2;
+        for (int i = 0; i < geom1MLS.numGeometries(); i++) {
+          for (int j = 0; j < geom2MLS.numGeometries(); j++) {
+            if (! (Boolean) super.execEvaluate(geom1MLS.geometryN(i), geom2MLS.geometryN(j),
+                sr)) {
+              return false;
+            }
+          }
+        }
+
+        return true;
+      }
+    }
+
+    return super.execEvaluate(geom1, geom2, sr);
+  }
 }
diff --git a/testdata/workloads/functional-query/queries/QueryTest/geospatial-esri-extra.test b/testdata/workloads/functional-query/queries/QueryTest/geospatial-esri-extra.test
index a7dfbab8f..694bc17e4 100644
--- a/testdata/workloads/functional-query/queries/QueryTest/geospatial-esri-extra.test
+++ b/testdata/workloads/functional-query/queries/QueryTest/geospatial-esri-extra.test
@@ -168,7 +168,7 @@ BIGINT
 7393893
 ====
 ---- QUERY
-select ST_Intersects(st_geomfromtext('LINESTRING(1 0, 1 1)'), st_geomfromtext('MULTILINESTRING((0 0, 0 1), (2 0, 2 1))'));
+select st_intersects(st_geomfromtext('LINESTRING(1 0, 1 1)'), st_geomfromtext('MULTILINESTRING((0 0, 0 1), (2 0, 2 1))'));
 ---- TYPES
 BOOLEAN
 ---- RESULTS
@@ -194,4 +194,32 @@ select st_intersects(st_geomfromtext('MULTILINESTRING((2 0, 2 2),(1 0, 1 1))'),
 BOOLEAN
 ---- RESULTS
 true
+====
+---- QUERY
+select st_disjoint(st_geomfromtext('LINESTRING(1 0, 1 1)'), st_geomfromtext('MULTILINESTRING((0 0, 0 1), (2 0, 2 1))'));
+---- TYPES
+BOOLEAN
+---- RESULTS
+true
+====
+---- QUERY
+select st_disjoint(st_geomfromtext('MULTILINESTRING((2 0, 2 2),(3 0, 3 2))'), st_geomfromtext('MULTILINESTRING((0 0, 0 2), (4 0, 4 2))'));
+---- TYPES
+BOOLEAN
+---- RESULTS
+true
+====
+---- QUERY
+select st_disjoint(st_geomfromtext('LINESTRING(1 0, 1 1)'), st_geomfromtext('MULTILINESTRING((-1 1, 2 1), (2 0, 2 1))'));
+---- TYPES
+BOOLEAN
+---- RESULTS
+false
+====
+---- QUERY
+select st_disjoint(st_geomfromtext('MULTILINESTRING((2 0, 2 2),(1 0, 1 1))'), st_geomfromtext('MULTILINESTRING((-1 1, 2 1), (2 0, 2 1))'));
+---- TYPES
+BOOLEAN
+---- RESULTS
+false
 ====
\ No newline at end of file