You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sedona.apache.org by ji...@apache.org on 2024/01/06 07:30:43 UTC
(sedona) branch snowflake-geojson-overload updated: Add ST_SubDivideExplodeV2 implementation but it is not supported in Snowflake
This is an automated email from the ASF dual-hosted git repository.
jiayu pushed a commit to branch snowflake-geojson-overload
in repository https://gitbox.apache.org/repos/asf/sedona.git
The following commit(s) were added to refs/heads/snowflake-geojson-overload by this push:
new a059a1258 Add ST_SubDivideExplodeV2 implementation but it is not supported in Snowflake
a059a1258 is described below
commit a059a1258849b0cdbacf1eec2accdfb381d32201
Author: Jia Yu <ji...@apache.org>
AuthorDate: Fri Jan 5 23:30:38 2024 -0800
Add ST_SubDivideExplodeV2 implementation but it is not supported in Snowflake
---
.../snowflake/snowsql/ddl/UDTFDDLGenerator.java | 24 ++++++---
.../snowsql/udtfs/ST_SubDivideExplodeV2.java | 60 ++++++++++++++++++++++
2 files changed, 76 insertions(+), 8 deletions(-)
diff --git a/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/ddl/UDTFDDLGenerator.java b/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/ddl/UDTFDDLGenerator.java
index c4710ce53..3424d3661 100644
--- a/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/ddl/UDTFDDLGenerator.java
+++ b/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/ddl/UDTFDDLGenerator.java
@@ -31,7 +31,11 @@ public class UDTFDDLGenerator {
ST_Envelope_Aggr.class,
ST_Union_Aggr.class,
ST_Collect.class,
- ST_Dump.class
+ ST_Dump.class,
+ // ST_SubDivideExplodeV2 is not supported in Snowflake.
+ // The error message is "java.lang.RuntimeException: net.snowflake.client.jdbc.SnowflakeSQLException: Data type GEOMETRY is not supported in non-SQL UDTF return type."
+ // Keep this comment here for future reference.
+// ST_SubDivideExplodeV2.class
};
public static String formatUDTFDDL(
@@ -39,6 +43,7 @@ public class UDTFDDLGenerator {
String schemaName,
Parameter[] argTypesRaw,
String[] argNames,
+ String[] argTypesCustom,
String returnType,
String stageName,
String handlerName,
@@ -59,7 +64,7 @@ public class UDTFDDLGenerator {
).replace(
"{KW_SCHEMA_NAME}", schemaName
).replace(
- "{KW_ARG_SPEC}", ArgSpecBuilder.args(argTypesRaw, argNames, new String[]{})
+ "{KW_ARG_SPEC}", ArgSpecBuilder.args(argTypesRaw, argNames, argTypesCustom)
).replace(
"{KW_RETURN_TYPE}", returnType
).replace(
@@ -77,7 +82,7 @@ public class UDTFDDLGenerator {
);
if (isNativeApp) {
ddl += "\n";
- ddl += "GRANT USAGE ON FUNCTION " + schemaName + "." + functionName + "(" + ArgSpecBuilder.argTypes(argTypesRaw, new String[]{}) + ") TO APPLICATION ROLE " + appRoleName + ";";
+ ddl += "GRANT USAGE ON FUNCTION " + schemaName + "." + functionName + "(" + ArgSpecBuilder.argTypes(argTypesRaw, argTypesCustom) + ") TO APPLICATION ROLE " + appRoleName + ";";
}
return ddl;
}
@@ -88,20 +93,23 @@ public class UDTFDDLGenerator {
Class outputRowClass = Arrays.stream(c.getDeclaredClasses()).filter(
cls -> cls.getName().endsWith("OutputRow")
).findFirst().get();
- String returnTypes = Arrays.stream(outputRowClass.getFields()).map(
- field -> field.getName() + " " + Constants.snowflakeTypeMap.get(field.getType().getTypeName())
- ).collect(Collectors.joining(", "));
+
Method processMethod = Arrays.stream(c.getDeclaredMethods()).filter(m -> m.getName().equals("process")).findFirst().get();
- Parameter[] paramTypes = processMethod.getParameters();
+ Parameter[] argTypesRaw = processMethod.getParameters();
String[] argNames = funcProps.argNames();
+ String[] argTypesCustom = funcProps.argTypes();
+ String returnTypes = Arrays.stream(outputRowClass.getFields()).map(
+ field -> field.getName() + " " + Constants.snowflakeTypeMap.get(funcProps.returnTypes().isEmpty()? field.getType().getTypeName() : funcProps.returnTypes())
+ ).collect(Collectors.joining(", "));
String handlerName = c.getPackage().getName() + "." + c.getSimpleName();
String null_input_conf = c.isAnnotationPresent(UDTFAnnotations.CallOnNull.class) ? "CALLED ON NULL INPUT" : "RETURNS NULL ON NULL INPUT";
String immutable_conf = c.isAnnotationPresent(UDTFAnnotations.Volatile.class) ? "VOLATILE" : "IMMUTABLE";
return formatUDTFDDL(
funcProps.name(),
configs.getOrDefault("schema", "sedona"),
- paramTypes,
+ argTypesRaw,
argNames,
+ argTypesCustom,
returnTypes,
stageName,
handlerName,
diff --git a/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/udtfs/ST_SubDivideExplodeV2.java b/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/udtfs/ST_SubDivideExplodeV2.java
new file mode 100644
index 000000000..da25e5980
--- /dev/null
+++ b/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/udtfs/ST_SubDivideExplodeV2.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sedona.snowflake.snowsql.udtfs;
+
+import org.apache.sedona.common.Functions;
+import org.apache.sedona.snowflake.snowsql.GeometrySerde;
+import org.apache.sedona.snowflake.snowsql.annotations.UDTFAnnotations;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.GeometryFactory;
+import org.locationtech.jts.io.ParseException;
+
+import java.util.stream.Stream;
+
+/**
+ * This class is a copy of ST_SubDivideExplode.java, but with the input and output types changed to Snowflake Geometry
+ * Unfortunately, Data type GEOMETRY is not supported in non-SQL UDTF return type.
+ * Just keep this class here for future reference.
+ * The error message is "java.lang.RuntimeException: net.snowflake.client.jdbc.SnowflakeSQLException: Data type GEOMETRY is not supported in non-SQL UDTF return type."
+ */
+@UDTFAnnotations.TabularFunc(name = "ST_SubDivideExplode", argNames = {"geom", "maxVertices"}, argTypes = {"Geometry", "int"}, returnTypes = "Geometry")
+public class ST_SubDivideExplodeV2
+{
+
+ public static final GeometryFactory geometryFactory = new GeometryFactory();
+
+ public static class OutputRow {
+
+ public String geom;
+
+ public OutputRow(String geom) {
+ this.geom = geom;
+ }
+ }
+
+ public static Class getOutputClass() {
+ return OutputRow.class;
+ }
+
+ public ST_SubDivideExplodeV2() {
+ }
+
+ public Stream<OutputRow> process(String geometry, int maxVertices) throws ParseException {
+ Geometry[] geometries = Functions.subDivide(
+ GeometrySerde.deserGeoJson(geometry),
+ maxVertices
+ );
+ return Stream.of(geometries).map(g -> new OutputRow(GeometrySerde.serGeoJson(g)));
+ }
+}