Skip to content

Commit

Permalink
feat: implement ST_MaxDistance
Browse files Browse the repository at this point in the history
Signed-off-by: Andreas Reichel <[email protected]>
Signed-off-by: manticore-projects <[email protected]>
  • Loading branch information
manticore-projects committed Dec 8, 2024
1 parent 0449077 commit f001573
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 17 deletions.
56 changes: 50 additions & 6 deletions src/main/java/ai/starlake/transpiler/JSQLExpressionTranspiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectItem;
import net.sf.jsqlparser.statement.select.TableFunction;
import net.sf.jsqlparser.util.deparser.ExpressionDeParser;
import net.sf.jsqlparser.util.deparser.SelectDeParser;

Expand Down Expand Up @@ -147,7 +148,7 @@ enum TranspiledFunction {
, FLOAT64, LAX_FLOAT64, INT64, LAX_INT64, LAX_STRING, JSON_QUERY, JSON_VALUE, JSON_QUERY_ARRAY, JSON_VALUE_ARRAY
, JSON_EXTRACT, JSON_EXTRACT_ARRAY, JSON_EXTRACT_SCALAR, JSON_EXTRACT_STRING_ARRAY, PARSE_JSON, TO_JSON, TO_JSON_STRING, NVL
, UNNEST, ST_GEOGPOINT, ST_GEOGFROMTEXT, ST_GEOGFROMGEOJSON, ST_GEOGFROMWKB, ST_ASBINARY, ST_ASGEOJSON, ST_ASTEXT
, ST_BUFFER, ST_NUMPOINTS, ST_DISTANCE, ST_BOUNDINGBOX, ST_EXTENT, ST_PERIMETER
, ST_BUFFER, ST_NUMPOINTS, ST_DISTANCE, ST_MAXDISTANCE, ST_BOUNDINGBOX, ST_EXTENT, ST_PERIMETER, ST_LENGTH
// GEO_MODE
, ST_AREA
;
Expand Down Expand Up @@ -1357,6 +1358,25 @@ ELSE JSON_VALUE('{"a.b":{"c":"world"}}','$."a.b".c')
function.setName("ST_NUMPOINTS");
function.setParameters(new CastExpression(parameters.get(0), "GEOMETRY"));
break;
case ST_LENGTH:
switch (paramCount) {
case 1:
switch (geoMode) {
case GEOMETRY:
function.setName("St_Length");
break;
case GEOGRAPHY:
function.setName("ST_Length_Spheroid");
break;
}
function.setParameters(new Function("ST_FLIPCOORDINATES", parameters.get(0)));
break;
case 2:
function.setName("ST_Length_Spheroid");
function.setParameters(new Function("ST_FLIPCOORDINATES", parameters.get(0)));
break;
}
break;
case ST_DISTANCE:
switch (paramCount) {
case 2:
Expand All @@ -1373,14 +1393,24 @@ ELSE JSON_VALUE('{"a.b":{"c":"world"}}','$."a.b".c')
break;
case 3:
rewrittenExpression = new Function("If", parameters.get(2),
new Function(
"ST_Distance_Spheroid", new Function("ST_FLIPCOORDINATES", parameters.get(0)),
new Function("ST_Distance_Spheroid",
new Function("ST_FLIPCOORDINATES", parameters.get(0)),
new Function("ST_FLIPCOORDINATES", parameters.get(1))),
new Function("ST_Distance$$", new Function("ST_FLIPCOORDINATES", parameters.get(0)),
new Function("ST_Distance_Sphere",
new Function("ST_FLIPCOORDINATES", parameters.get(0)),
new Function("ST_FLIPCOORDINATES", parameters.get(1))));
break;
}
break;
case ST_MAXDISTANCE:
// SELECT ( select max_distance from ST_MaxDistance(st_geomfromtext('LINESTRING(0 0, 0 1,
// 1 1, 1 0, 0 0)'), st_geomfromtext('LINESTRING(10 0, 10 1, 11 1, 11 0, 10 0)')) )
// max_distance;
TableFunction tableFunction =
new TableFunction("ST_MaxDistance$$", parameters.get(0), parameters.get(1));
rewrittenExpression =
new ParenthesedSelect(List.of(new Column("max_distance")), tableFunction);
break;
case ST_BOUNDINGBOX:
// not aggregated version of EXTEND
function.setName("ST_EXTENT");
Expand All @@ -1391,8 +1421,22 @@ ELSE JSON_VALUE('{"a.b":{"c":"world"}}','$."a.b".c')
function.setName("ST_Extent_Agg");
break;
case ST_PERIMETER:
if (paramCount > 3) {
warning("USE_SPHEROID is not supported.");
switch (paramCount) {
case 1:
switch (geoMode) {
case GEOMETRY:
function.setName("St_Perimeter");
break;
case GEOGRAPHY:
function.setName("ST_Perimeter_Spheroid");
break;
}
function.setParameters(new Function("ST_FLIPCOORDINATES", parameters.get(0)));
break;
case 2:
function.setName("ST_Perimeter_Spheroid");
function.setParameters(new Function("ST_FLIPCOORDINATES", parameters.get(0)));
break;
}
break;
case ST_AREA:
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
CREATE OR REPLACE FUNCTION ifplus(a, b, c) AS CASE a WHEN b THEN b ELSE a + c END;
CREATE OR REPLACE FUNCTION ifplus(a, b, c) AS CASE a WHEN b THEN b ELSE a + c END;

CREATE OR REPLACE FUNCTION ST_MaxDistance(a, b) AS TABLE
(
SELECT max(ST_DISTANCE_SPHERE(ST_FlipCoordinates(g1.UNNEST.geom), ST_FlipCoordinates(g2.UNNEST.geom))) AS max_distance
FROM
UNNEST(st_dump(st_points(a))) AS g1
, UNNEST(st_dump(st_points(b))) AS g2
);
20 changes: 10 additions & 10 deletions src/test/resources/ai/starlake/transpiler/bigquery/geography.sql
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ SELECT IF(TRUE
,ST_DISTANCE_SPHEROID(
ST_FLIPCOORDINATES(ST_GEOMFROMTEXT('POINT(2.3058359 48.858904)'))
,ST_FLIPCOORDINATES(ST_GEOMFROMTEXT('POINT(11.4594367 48.1549958)')))
,ST_DISTANCE(
,ST_DISTANCE_SPHERE(
ST_FLIPCOORDINATES(ST_GEOMFROMTEXT('POINT(2.3058359 48.858904)'))
,ST_FLIPCOORDINATES(ST_GEOMFROMTEXT('POINT(11.4594367 48.1549958)')))
)/1000 AS KM;
Expand All @@ -41,33 +41,33 @@ SELECT ST_DISTANCE_SPHERE(


-- provided
SELECT st_length(st_geogfromtext("LINESTRING(0 0, 0 1, 1 1, 1 0, 0 0)")) as geo
SELECT st_length(st_geogfromtext("LINESTRING(0 0, 0 1, 1 1, 1 0, 0 0)")) as geo;

-- expected
SELECT /* APPROXIMATION: ST_LENGTH SPHERE */ st_length_spheroid(st_flipcoordinates(st_geomfromtext('LINESTRING(0 0, 0 1, 1 1, 1 0, 0 0)'))) as geo
SELECT /* APPROXIMATION: ST_LENGTH SPHERE */ st_length_spheroid(st_flipcoordinates(st_geomfromtext('LINESTRING(0 0, 0 1, 1 1, 1 0, 0 0)'))) as geo;

-- results
"geo"
443770.91724830196
"443770.917248302"


-- provided
SELECT st_maxdistance(st_geogfromtext('LINESTRING(0 0, 0 1, 1 1, 1 0, 0 0)'), st_geogfromtext('LINESTRING(10 0, 10 1, 11 1, 11 0, 10 0)'))
SELECT st_maxdistance(st_geogfromtext('LINESTRING(0 0, 0 1, 1 1, 1 0, 0 0)'), st_geogfromtext('LINESTRING(10 0, 10 1, 11 1, 11 0, 10 0)')) max_distance;

-- expected
SELECT max(ST_DISTANCE_SPHERE(ST_FlipCoordinates(g1.UNNEST.geom), ST_FlipCoordinates(g2.UNNEST.geom))) AS max_distance FROM UNNEST(st_dump(st_points(st_geomfromtext('LINESTRING(0 0, 0 1, 1 1, 1 0, 0 0)')))) AS g1, UNNEST(st_dump(st_points(st_geomfromtext('LINESTRING(10 0, 10 1, 11 1, 11 0, 10 0)')))) g2
SELECT(SELECT MAX_DISTANCE FROM ST_MAXDISTANCE(ST_GEOMFROMTEXT('LINESTRING(0 0,0 1,1 1,1 0,0 0)'),ST_GEOMFROMTEXT('LINESTRING(10 0,10 1,11 1,11 0,10 0)')))AS MAX_DISTANCE;

-- result
"max_distance"
1228126.109277834
"1228126.109277834"


-- provided
SELECT st_perimeter(st_geogfromtext('POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))')) as perimeter
SELECT st_perimeter(st_geogfromtext('POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))')) as perimeter;

-- expected
SELECT st_perimeter_spheroid(st_geomfromtext('POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))')) as perimeter
SELECT ST_PERIMETER_SPHEROID(ST_FLIPCOORDINATES(ST_GEOMFROMTEXT('POLYGON((0 0,0 1,1 1,1 0,0 0))')))AS PERIMETER;

-- result
"perimeter"
443770.91724830196
"443770.917248302"

0 comments on commit f001573

Please sign in to comment.