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

jackie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new 8df722a22f Add some missing geospatial scalar functions to support use 
in intermediate stages with the v2 query engine (#13457)
8df722a22f is described below

commit 8df722a22f089d088bfb03e2b8aa49549bc4c38c
Author: Yash Mayya <yash.ma...@gmail.com>
AuthorDate: Sun Jun 23 04:39:00 2024 +0530

    Add some missing geospatial scalar functions to support use in intermediate 
stages with the v2 query engine (#13457)
---
 .../transform/function/ScalarFunctions.java        | 36 ++++++++++++++++++++++
 .../integration/tests/custom/GeoSpatialTest.java   | 33 ++++++++++++++++++++
 2 files changed, 69 insertions(+)

diff --git 
a/pinot-core/src/main/java/org/apache/pinot/core/geospatial/transform/function/ScalarFunctions.java
 
b/pinot-core/src/main/java/org/apache/pinot/core/geospatial/transform/function/ScalarFunctions.java
index d8c37c3bd7..2d259c03a7 100644
--- 
a/pinot-core/src/main/java/org/apache/pinot/core/geospatial/transform/function/ScalarFunctions.java
+++ 
b/pinot-core/src/main/java/org/apache/pinot/core/geospatial/transform/function/ScalarFunctions.java
@@ -188,4 +188,40 @@ public class ScalarFunctions {
       return firstGeometry.isEmpty() || secondGeometry.isEmpty() ? Double.NaN 
: firstGeometry.distance(secondGeometry);
     }
   }
+
+  @ScalarFunction(names = {"stContains", "st_contains"})
+  public static int stContains(byte[] first, byte[] second) {
+    Geometry firstGeometry = GeometrySerializer.deserialize(first);
+    Geometry secondGeometry = GeometrySerializer.deserialize(second);
+    if (GeometryUtils.isGeography(firstGeometry) != 
GeometryUtils.isGeography(secondGeometry)) {
+      throw new RuntimeException("The first and second arguments should either 
both be geometry or both be geography");
+    }
+    // TODO: to fully support Geography contains operation.
+    return firstGeometry.contains(secondGeometry) ? 1 : 0;
+  }
+
+  @ScalarFunction(names = {"stEquals", "st_equals"})
+  public static int stEquals(byte[] first, byte[] second) {
+    Geometry firstGeometry = GeometrySerializer.deserialize(first);
+    Geometry secondGeometry = GeometrySerializer.deserialize(second);
+
+    return firstGeometry.equals(secondGeometry) ? 1 : 0;
+  }
+
+  @ScalarFunction(names = {"stGeometryType", "st_geometry_type"})
+  public static String stGeometryType(byte[] bytes) {
+    Geometry geometry = GeometrySerializer.deserialize(bytes);
+    return geometry.getGeometryType();
+  }
+
+  @ScalarFunction(names = {"stWithin", "st_within"})
+  public static int stWithin(byte[] first, byte[] second) {
+    Geometry firstGeometry = GeometrySerializer.deserialize(first);
+    Geometry secondGeometry = GeometrySerializer.deserialize(second);
+    if (GeometryUtils.isGeography(firstGeometry) != 
GeometryUtils.isGeography(secondGeometry)) {
+      throw new RuntimeException("The first and second arguments should either 
both be geometry or both be geography");
+    }
+    // TODO: to fully support Geography within operation.
+    return firstGeometry.within(secondGeometry) ? 1 : 0;
+  }
 }
diff --git 
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/custom/GeoSpatialTest.java
 
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/custom/GeoSpatialTest.java
index ff41c76b13..b5cf20019b 100644
--- 
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/custom/GeoSpatialTest.java
+++ 
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/custom/GeoSpatialTest.java
@@ -404,6 +404,39 @@ public class GeoSpatialTest extends 
CustomDataQueryClusterIntegrationTest {
     }
   }
 
+  @Test(dataProvider = "useBothQueryEngines")
+  public void testStContainsQuery(boolean useMultiStageQueryEngine) throws 
Exception {
+    setUseMultiStageQueryEngine(useMultiStageQueryEngine);
+    // contains is the converse of within
+    String query =
+        String.format("Select ST_Contains(ST_GeomFromText(%s), 
ST_GeomFromText(%s)), %s from %s",
+            WKT_2_NAME, WKT_1_NAME, ST_WITHIN_RESULT_NAME, getTableName());
+    JsonNode pinotResponse = postQuery(query);
+    JsonNode rows = pinotResponse.get("resultTable").get("rows");
+    for (int i = 0; i < rows.size(); i++) {
+      JsonNode row = rows.get(i);
+      boolean actualResult = row.get(0).intValue() == 1;
+      boolean expectedResult = row.get(1).booleanValue();
+      Assert.assertEquals(actualResult, expectedResult);
+    }
+  }
+
+  @Test(dataProvider = "useV2QueryEngine")
+  public void testStContainsQueryWithV2(boolean useMultiStageQueryEngine) 
throws Exception {
+    setUseMultiStageQueryEngine(useMultiStageQueryEngine);
+
+    String query = String.format("Select 
ST_Contains(ST_GeomFromText('MULTIPOINT (20 20, 25 25)'), "
+        + "ST_GeomFromText('POINT (25 25)')) from %s a CROSS JOIN %s b LIMIT 
5", getTableName(), getTableName());
+
+    JsonNode pinotResponse = postQuery(query);
+    JsonNode rows = pinotResponse.get("resultTable").get("rows");
+    for (int i = 0; i < rows.size(); i++) {
+      JsonNode row = rows.get(i);
+      boolean actualResult = row.get(0).intValue() == 1;
+      Assert.assertTrue(actualResult);
+    }
+  }
+
   @Test(dataProvider = "useV2QueryEngine")
   public void testStWithinLiteral(boolean useMultiStageQueryEngine)
       throws Exception {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org
For additional commands, e-mail: commits-h...@pinot.apache.org

Reply via email to