Skip to content

Commit 9b68d3c

Browse files
uros-dbdongjoon-hyun
authored andcommitted
[SPARK-54244][GEO][SQL] Introduce type coercion support for GEOMETRY data types
### What changes were proposed in this pull request? Implement least common type (LCT) logic for `GEOMETRY` types, as follows: - LCT for GeometryType(`srid_1`) and GeometryType(`srid_1`) is: GeometryType(`srid_1`) - LCT for GeometryType(`srid_1`) and GeometryType(`srid_2`) is: GeometryType(`ANY`) - LCT for GeometryType(`srid_1`) and GeometryType(`ANY`) is: GeometryType(`ANY`) - LCT for GeometryType(`ANY`) and GeometryType(`ANY`) is: GeometryType(`ANY`) In other words, the mixed SRID `GEOMETRY` type is the *common type* for all GEOMETRY types. ### Why are the changes needed? Introducing LCT and type coercion logic in the geospatial data type system. ### Does this PR introduce _any_ user-facing change? Yes, type coercion is now supported for `GeometryType`. ### How was this patch tested? Added tests for geometry type coercion: - `AnsiTypeCoercionSuite` - `TypeCoercionSuite` Added appropriate Scala suite unit tests: - `STExpressionsSuite` Added appropriate end-to-end SQL tests: - `st-functions` ### Was this patch authored or co-authored using generative AI tooling? No. Closes #52945 from uros-db/geo-coercion-geom. Authored-by: Uros Bojanic <uros.bojanic@databricks.com> Signed-off-by: Dongjoon Hyun <dongjoon@apache.org>
1 parent b144965 commit 9b68d3c

File tree

10 files changed

+491
-0
lines changed

10 files changed

+491
-0
lines changed

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/AnsiTypeCoercion.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ object AnsiTypeCoercion extends TypeCoercionBase {
133133
// We allow coercion from GEOGRAPHY(<srid>) types (i.e. fixed SRID types) to the
134134
// GEOGRAPHY(ANY) type (i.e. mixed SRID type). This coercion is always safe to do.
135135
case (t1: GeographyType, t2: GeographyType) if t1 != t2 => Some(GeographyType("ANY"))
136+
// We allow coercion from GEOMETRY(<srid>) types (i.e. fixed SRID types) to the
137+
// GEOMETRY(ANY) type (i.e. mixed SRID type). This coercion is always safe to do.
138+
case (t1: GeometryType, t2: GeometryType) if t1 != t2 => Some(GeometryType("ANY"))
136139

137140
case (t1, t2) => findTypeForComplex(t1, t2, findTightestCommonType)
138141
}

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercion.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ object TypeCoercion extends TypeCoercionBase {
101101
// We allow coercion from GEOGRAPHY(<srid>) types (i.e. fixed SRID types) to the
102102
// GEOGRAPHY(ANY) type (i.e. mixed SRID type). This coercion is always safe to do.
103103
case (t1: GeographyType, t2: GeographyType) if t1 != t2 => Some(GeographyType("ANY"))
104+
// We allow coercion from GEOMETRY(<srid>) types (i.e. fixed SRID types) to the
105+
// GEOMETRY(ANY) type (i.e. mixed SRID type). This coercion is always safe to do.
106+
case (t1: GeometryType, t2: GeometryType) if t1 != t2 => Some(GeometryType("ANY"))
104107

105108
case (t1, t2) => findTypeForComplex(t1, t2, findTightestCommonType)
106109
}

sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnsiTypeCoercionSuite.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,18 @@ class AnsiTypeCoercionSuite extends TypeCoercionSuiteBase {
180180
widenTest(GeographyType("ANY"), GeographyType("ANY"), Some(GeographyType("ANY")))
181181
widenTest(GeographyType("ANY"), GeographyType(4326), Some(GeographyType("ANY")))
182182
widenTest(GeographyType(4326), GeographyType("ANY"), Some(GeographyType("ANY")))
183+
// Geometry with same fixed SRIDs.
184+
widenTest(GeometryType(0), GeometryType(0), Some(GeometryType(0)))
185+
widenTest(GeometryType(3857), GeometryType(3857), Some(GeometryType(3857)))
186+
widenTest(GeometryType(4326), GeometryType(4326), Some(GeometryType(4326)))
187+
// Geometry with different fixed SRIDs.
188+
widenTest(GeometryType(0), GeometryType(3857), Some(GeometryType("ANY")))
189+
widenTest(GeometryType(3857), GeometryType(4326), Some(GeometryType("ANY")))
190+
widenTest(GeometryType(4326), GeometryType(0), Some(GeometryType("ANY")))
191+
// Geometry with mixed SRIDs.
192+
widenTest(GeometryType("ANY"), GeometryType("ANY"), Some(GeometryType("ANY")))
193+
widenTest(GeometryType("ANY"), GeometryType(4326), Some(GeometryType("ANY")))
194+
widenTest(GeometryType(4326), GeometryType("ANY"), Some(GeometryType("ANY")))
183195

184196
// Integral mixed with floating point.
185197
widenTest(IntegerType, FloatType, Some(DoubleType))

sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/TypeCoercionSuite.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,18 @@ class TypeCoercionSuite extends TypeCoercionSuiteBase {
603603
widenTest(GeographyType("ANY"), GeographyType("ANY"), Some(GeographyType("ANY")))
604604
widenTest(GeographyType("ANY"), GeographyType(4326), Some(GeographyType("ANY")))
605605
widenTest(GeographyType(4326), GeographyType("ANY"), Some(GeographyType("ANY")))
606+
// Geometry with same fixed SRIDs.
607+
widenTest(GeometryType(0), GeometryType(0), Some(GeometryType(0)))
608+
widenTest(GeometryType(3857), GeometryType(3857), Some(GeometryType(3857)))
609+
widenTest(GeometryType(4326), GeometryType(4326), Some(GeometryType(4326)))
610+
// Geometry with different fixed SRIDs.
611+
widenTest(GeometryType(0), GeometryType(3857), Some(GeometryType("ANY")))
612+
widenTest(GeometryType(3857), GeometryType(4326), Some(GeometryType("ANY")))
613+
widenTest(GeometryType(4326), GeometryType(0), Some(GeometryType("ANY")))
614+
// Geometry with mixed SRIDs.
615+
widenTest(GeometryType("ANY"), GeometryType("ANY"), Some(GeometryType("ANY")))
616+
widenTest(GeometryType("ANY"), GeometryType(4326), Some(GeometryType("ANY")))
617+
widenTest(GeometryType(4326), GeometryType("ANY"), Some(GeometryType("ANY")))
606618

607619
// Integral mixed with floating point.
608620
widenTest(IntegerType, FloatType, Some(FloatType))

sql/core/src/test/resources/sql-tests/analyzer-results/nonansi/st-functions.sql.out

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,14 @@ Project [typeof(array(cast(st_geogfromwkb(wkb#x) as geography(any)), cast(st_geo
161161
+- Relation spark_catalog.default.geodata[wkb#x] parquet
162162

163163

164+
-- !query
165+
SELECT typeof(array(ST_GeomFromWKB(wkb), ST_GeomFromWKB(wkb)::GEOMETRY(ANY))) FROM geodata
166+
-- !query analysis
167+
Project [typeof(array(cast(st_geomfromwkb(wkb#x) as geometry(any)), cast(st_geomfromwkb(wkb#x) as geometry(any)))) AS typeof(array(st_geomfromwkb(wkb), CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY))))#x]
168+
+- SubqueryAlias spark_catalog.default.geodata
169+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
170+
171+
164172
-- !query
165173
SELECT typeof(map('a', ST_GeogFromWKB(wkb), 'b', ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY))) FROM geodata
166174
-- !query analysis
@@ -169,6 +177,14 @@ Project [typeof(map(a, cast(st_geogfromwkb(wkb#x) as geography(any)), b, cast(st
169177
+- Relation spark_catalog.default.geodata[wkb#x] parquet
170178

171179

180+
-- !query
181+
SELECT typeof(map('a', ST_GeomFromWKB(wkb), 'b', ST_GeomFromWKB(wkb)::GEOMETRY(ANY))) FROM geodata
182+
-- !query analysis
183+
Project [typeof(map(a, cast(st_geomfromwkb(wkb#x) as geometry(any)), b, cast(st_geomfromwkb(wkb#x) as geometry(any)))) AS typeof(map(a, st_geomfromwkb(wkb), b, CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY))))#x]
184+
+- SubqueryAlias spark_catalog.default.geodata
185+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
186+
187+
172188
-- !query
173189
SELECT typeof(array(named_struct('g1', ST_GeogFromWKB(wkb), 'g2', ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY)), named_struct('g1', ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY), 'g2', ST_GeogFromWKB(wkb)))) FROM geodata
174190
-- !query analysis
@@ -177,6 +193,14 @@ Project [typeof(array(cast(named_struct(g1, st_geogfromwkb(wkb#x), g2, cast(st_g
177193
+- Relation spark_catalog.default.geodata[wkb#x] parquet
178194

179195

196+
-- !query
197+
SELECT typeof(array(named_struct('g1', ST_GeomFromWKB(wkb), 'g2', ST_GeomFromWKB(wkb)::GEOMETRY(ANY)), named_struct('g1', ST_GeomFromWKB(wkb)::GEOMETRY(ANY), 'g2', ST_GeomFromWKB(wkb)))) FROM geodata
198+
-- !query analysis
199+
Project [typeof(array(cast(named_struct(g1, st_geomfromwkb(wkb#x), g2, cast(st_geomfromwkb(wkb#x) as geometry(any))) as struct<g1:geometry(any),g2:geometry(any)>), cast(named_struct(g1, cast(st_geomfromwkb(wkb#x) as geometry(any)), g2, st_geomfromwkb(wkb#x)) as struct<g1:geometry(any),g2:geometry(any)>))) AS typeof(array(named_struct(g1, st_geomfromwkb(wkb), g2, CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY))), named_struct(g1, CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY)), g2, st_geomfromwkb(wkb))))#x]
200+
+- SubqueryAlias spark_catalog.default.geodata
201+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
202+
203+
180204
-- !query
181205
SELECT typeof(named_struct('a', array(ST_GeogFromWKB(wkb), ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY)), 'b', map('g', ST_GeogFromWKB(wkb), 'h', ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY)))) FROM geodata
182206
-- !query analysis
@@ -185,6 +209,14 @@ Project [typeof(named_struct(a, array(cast(st_geogfromwkb(wkb#x) as geography(an
185209
+- Relation spark_catalog.default.geodata[wkb#x] parquet
186210

187211

212+
-- !query
213+
SELECT typeof(named_struct('a', array(ST_GeomFromWKB(wkb), ST_GeomFromWKB(wkb)::GEOMETRY(ANY)), 'b', map('g', ST_GeomFromWKB(wkb), 'h', ST_GeomFromWKB(wkb)::GEOMETRY(ANY)))) FROM geodata
214+
-- !query analysis
215+
Project [typeof(named_struct(a, array(cast(st_geomfromwkb(wkb#x) as geometry(any)), cast(st_geomfromwkb(wkb#x) as geometry(any))), b, map(g, cast(st_geomfromwkb(wkb#x) as geometry(any)), h, cast(st_geomfromwkb(wkb#x) as geometry(any))))) AS typeof(named_struct(a, array(st_geomfromwkb(wkb), CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY))), b, map(g, st_geomfromwkb(wkb), h, CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY)))))#x]
216+
+- SubqueryAlias spark_catalog.default.geodata
217+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
218+
219+
188220
-- !query
189221
SELECT typeof(nvl(ST_GeogFromWKB(wkb), ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY))) FROM geodata
190222
-- !query analysis
@@ -193,6 +225,14 @@ Project [typeof(nvl(st_geogfromwkb(wkb#x), cast(st_geogfromwkb(wkb#x) as geograp
193225
+- Relation spark_catalog.default.geodata[wkb#x] parquet
194226

195227

228+
-- !query
229+
SELECT typeof(nvl(ST_GeomFromWKB(wkb), ST_GeomFromWKB(wkb)::GEOMETRY(ANY))) FROM geodata
230+
-- !query analysis
231+
Project [typeof(nvl(st_geomfromwkb(wkb#x), cast(st_geomfromwkb(wkb#x) as geometry(any)))) AS typeof(nvl(st_geomfromwkb(wkb), CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY))))#x]
232+
+- SubqueryAlias spark_catalog.default.geodata
233+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
234+
235+
196236
-- !query
197237
SELECT typeof(nvl2(ST_GeogFromWKB(wkb), ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY), ST_GeogFromWKB(wkb))) FROM geodata
198238
-- !query analysis
@@ -201,6 +241,14 @@ Project [typeof(nvl2(st_geogfromwkb(wkb#x), cast(st_geogfromwkb(wkb#x) as geogra
201241
+- Relation spark_catalog.default.geodata[wkb#x] parquet
202242

203243

244+
-- !query
245+
SELECT typeof(nvl2(ST_GeomFromWKB(wkb), ST_GeomFromWKB(wkb)::GEOMETRY(ANY), ST_GeomFromWKB(wkb))) FROM geodata
246+
-- !query analysis
247+
Project [typeof(nvl2(st_geomfromwkb(wkb#x), cast(st_geomfromwkb(wkb#x) as geometry(any)), st_geomfromwkb(wkb#x))) AS typeof(nvl2(st_geomfromwkb(wkb), CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY)), st_geomfromwkb(wkb)))#x]
248+
+- SubqueryAlias spark_catalog.default.geodata
249+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
250+
251+
204252
-- !query
205253
SELECT typeof(CASE WHEN wkb IS NOT NULL THEN ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY) ELSE ST_GeogFromWKB(wkb) END) FROM geodata
206254
-- !query analysis
@@ -209,6 +257,14 @@ Project [typeof(CASE WHEN isnotnull(wkb#x) THEN cast(st_geogfromwkb(wkb#x) as ge
209257
+- Relation spark_catalog.default.geodata[wkb#x] parquet
210258

211259

260+
-- !query
261+
SELECT typeof(CASE WHEN wkb IS NOT NULL THEN ST_GeomFromWKB(wkb)::GEOMETRY(ANY) ELSE ST_GeomFromWKB(wkb) END) FROM geodata
262+
-- !query analysis
263+
Project [typeof(CASE WHEN isnotnull(wkb#x) THEN cast(st_geomfromwkb(wkb#x) as geometry(any)) ELSE cast(st_geomfromwkb(wkb#x) as geometry(any)) END) AS typeof(CASE WHEN (wkb IS NOT NULL) THEN CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY)) ELSE st_geomfromwkb(wkb) END)#x]
264+
+- SubqueryAlias spark_catalog.default.geodata
265+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
266+
267+
212268
-- !query
213269
SELECT typeof(coalesce(ST_GeogFromWKB(wkb), ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY))) FROM geodata
214270
-- !query analysis
@@ -217,6 +273,14 @@ Project [typeof(coalesce(cast(st_geogfromwkb(wkb#x) as geography(any)), cast(st_
217273
+- Relation spark_catalog.default.geodata[wkb#x] parquet
218274

219275

276+
-- !query
277+
SELECT typeof(coalesce(ST_GeomFromWKB(wkb), ST_GeomFromWKB(wkb)::GEOMETRY(ANY))) FROM geodata
278+
-- !query analysis
279+
Project [typeof(coalesce(cast(st_geomfromwkb(wkb#x) as geometry(any)), cast(st_geomfromwkb(wkb#x) as geometry(any)))) AS typeof(coalesce(st_geomfromwkb(wkb), CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY))))#x]
280+
+- SubqueryAlias spark_catalog.default.geodata
281+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
282+
283+
220284
-- !query
221285
SELECT typeof(IF(wkb IS NOT NULL, ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY), ST_GeogFromWKB(wkb))) FROM geodata
222286
-- !query analysis
@@ -225,6 +289,14 @@ Project [typeof(if (isnotnull(wkb#x)) cast(st_geogfromwkb(wkb#x) as geography(an
225289
+- Relation spark_catalog.default.geodata[wkb#x] parquet
226290

227291

292+
-- !query
293+
SELECT typeof(IF(wkb IS NOT NULL, ST_GeomFromWKB(wkb)::GEOMETRY(ANY), ST_GeomFromWKB(wkb))) FROM geodata
294+
-- !query analysis
295+
Project [typeof(if (isnotnull(wkb#x)) cast(st_geomfromwkb(wkb#x) as geometry(any)) else cast(st_geomfromwkb(wkb#x) as geometry(any))) AS typeof((IF((wkb IS NOT NULL), CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY)), st_geomfromwkb(wkb))))#x]
296+
+- SubqueryAlias spark_catalog.default.geodata
297+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
298+
299+
228300
-- !query
229301
SELECT hex(ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000f03f0000000000000040'))) AS result
230302
-- !query analysis

sql/core/src/test/resources/sql-tests/analyzer-results/st-functions.sql.out

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,14 @@ Project [typeof(array(cast(st_geogfromwkb(wkb#x) as geography(any)), cast(st_geo
161161
+- Relation spark_catalog.default.geodata[wkb#x] parquet
162162

163163

164+
-- !query
165+
SELECT typeof(array(ST_GeomFromWKB(wkb), ST_GeomFromWKB(wkb)::GEOMETRY(ANY))) FROM geodata
166+
-- !query analysis
167+
Project [typeof(array(cast(st_geomfromwkb(wkb#x) as geometry(any)), cast(st_geomfromwkb(wkb#x) as geometry(any)))) AS typeof(array(st_geomfromwkb(wkb), CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY))))#x]
168+
+- SubqueryAlias spark_catalog.default.geodata
169+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
170+
171+
164172
-- !query
165173
SELECT typeof(map('a', ST_GeogFromWKB(wkb), 'b', ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY))) FROM geodata
166174
-- !query analysis
@@ -169,6 +177,14 @@ Project [typeof(map(a, cast(st_geogfromwkb(wkb#x) as geography(any)), b, cast(st
169177
+- Relation spark_catalog.default.geodata[wkb#x] parquet
170178

171179

180+
-- !query
181+
SELECT typeof(map('a', ST_GeomFromWKB(wkb), 'b', ST_GeomFromWKB(wkb)::GEOMETRY(ANY))) FROM geodata
182+
-- !query analysis
183+
Project [typeof(map(a, cast(st_geomfromwkb(wkb#x) as geometry(any)), b, cast(st_geomfromwkb(wkb#x) as geometry(any)))) AS typeof(map(a, st_geomfromwkb(wkb), b, CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY))))#x]
184+
+- SubqueryAlias spark_catalog.default.geodata
185+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
186+
187+
172188
-- !query
173189
SELECT typeof(array(named_struct('g1', ST_GeogFromWKB(wkb), 'g2', ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY)), named_struct('g1', ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY), 'g2', ST_GeogFromWKB(wkb)))) FROM geodata
174190
-- !query analysis
@@ -177,6 +193,14 @@ Project [typeof(array(cast(named_struct(g1, st_geogfromwkb(wkb#x), g2, cast(st_g
177193
+- Relation spark_catalog.default.geodata[wkb#x] parquet
178194

179195

196+
-- !query
197+
SELECT typeof(array(named_struct('g1', ST_GeomFromWKB(wkb), 'g2', ST_GeomFromWKB(wkb)::GEOMETRY(ANY)), named_struct('g1', ST_GeomFromWKB(wkb)::GEOMETRY(ANY), 'g2', ST_GeomFromWKB(wkb)))) FROM geodata
198+
-- !query analysis
199+
Project [typeof(array(cast(named_struct(g1, st_geomfromwkb(wkb#x), g2, cast(st_geomfromwkb(wkb#x) as geometry(any))) as struct<g1:geometry(any),g2:geometry(any)>), cast(named_struct(g1, cast(st_geomfromwkb(wkb#x) as geometry(any)), g2, st_geomfromwkb(wkb#x)) as struct<g1:geometry(any),g2:geometry(any)>))) AS typeof(array(named_struct(g1, st_geomfromwkb(wkb), g2, CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY))), named_struct(g1, CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY)), g2, st_geomfromwkb(wkb))))#x]
200+
+- SubqueryAlias spark_catalog.default.geodata
201+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
202+
203+
180204
-- !query
181205
SELECT typeof(named_struct('a', array(ST_GeogFromWKB(wkb), ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY)), 'b', map('g', ST_GeogFromWKB(wkb), 'h', ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY)))) FROM geodata
182206
-- !query analysis
@@ -185,6 +209,14 @@ Project [typeof(named_struct(a, array(cast(st_geogfromwkb(wkb#x) as geography(an
185209
+- Relation spark_catalog.default.geodata[wkb#x] parquet
186210

187211

212+
-- !query
213+
SELECT typeof(named_struct('a', array(ST_GeomFromWKB(wkb), ST_GeomFromWKB(wkb)::GEOMETRY(ANY)), 'b', map('g', ST_GeomFromWKB(wkb), 'h', ST_GeomFromWKB(wkb)::GEOMETRY(ANY)))) FROM geodata
214+
-- !query analysis
215+
Project [typeof(named_struct(a, array(cast(st_geomfromwkb(wkb#x) as geometry(any)), cast(st_geomfromwkb(wkb#x) as geometry(any))), b, map(g, cast(st_geomfromwkb(wkb#x) as geometry(any)), h, cast(st_geomfromwkb(wkb#x) as geometry(any))))) AS typeof(named_struct(a, array(st_geomfromwkb(wkb), CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY))), b, map(g, st_geomfromwkb(wkb), h, CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY)))))#x]
216+
+- SubqueryAlias spark_catalog.default.geodata
217+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
218+
219+
188220
-- !query
189221
SELECT typeof(nvl(ST_GeogFromWKB(wkb), ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY))) FROM geodata
190222
-- !query analysis
@@ -193,6 +225,14 @@ Project [typeof(nvl(st_geogfromwkb(wkb#x), cast(st_geogfromwkb(wkb#x) as geograp
193225
+- Relation spark_catalog.default.geodata[wkb#x] parquet
194226

195227

228+
-- !query
229+
SELECT typeof(nvl(ST_GeomFromWKB(wkb), ST_GeomFromWKB(wkb)::GEOMETRY(ANY))) FROM geodata
230+
-- !query analysis
231+
Project [typeof(nvl(st_geomfromwkb(wkb#x), cast(st_geomfromwkb(wkb#x) as geometry(any)))) AS typeof(nvl(st_geomfromwkb(wkb), CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY))))#x]
232+
+- SubqueryAlias spark_catalog.default.geodata
233+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
234+
235+
196236
-- !query
197237
SELECT typeof(nvl2(ST_GeogFromWKB(wkb), ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY), ST_GeogFromWKB(wkb))) FROM geodata
198238
-- !query analysis
@@ -201,6 +241,14 @@ Project [typeof(nvl2(st_geogfromwkb(wkb#x), cast(st_geogfromwkb(wkb#x) as geogra
201241
+- Relation spark_catalog.default.geodata[wkb#x] parquet
202242

203243

244+
-- !query
245+
SELECT typeof(nvl2(ST_GeomFromWKB(wkb), ST_GeomFromWKB(wkb)::GEOMETRY(ANY), ST_GeomFromWKB(wkb))) FROM geodata
246+
-- !query analysis
247+
Project [typeof(nvl2(st_geomfromwkb(wkb#x), cast(st_geomfromwkb(wkb#x) as geometry(any)), st_geomfromwkb(wkb#x))) AS typeof(nvl2(st_geomfromwkb(wkb), CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY)), st_geomfromwkb(wkb)))#x]
248+
+- SubqueryAlias spark_catalog.default.geodata
249+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
250+
251+
204252
-- !query
205253
SELECT typeof(CASE WHEN wkb IS NOT NULL THEN ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY) ELSE ST_GeogFromWKB(wkb) END) FROM geodata
206254
-- !query analysis
@@ -209,6 +257,14 @@ Project [typeof(CASE WHEN isnotnull(wkb#x) THEN cast(st_geogfromwkb(wkb#x) as ge
209257
+- Relation spark_catalog.default.geodata[wkb#x] parquet
210258

211259

260+
-- !query
261+
SELECT typeof(CASE WHEN wkb IS NOT NULL THEN ST_GeomFromWKB(wkb)::GEOMETRY(ANY) ELSE ST_GeomFromWKB(wkb) END) FROM geodata
262+
-- !query analysis
263+
Project [typeof(CASE WHEN isnotnull(wkb#x) THEN cast(st_geomfromwkb(wkb#x) as geometry(any)) ELSE cast(st_geomfromwkb(wkb#x) as geometry(any)) END) AS typeof(CASE WHEN (wkb IS NOT NULL) THEN CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY)) ELSE st_geomfromwkb(wkb) END)#x]
264+
+- SubqueryAlias spark_catalog.default.geodata
265+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
266+
267+
212268
-- !query
213269
SELECT typeof(coalesce(ST_GeogFromWKB(wkb), ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY))) FROM geodata
214270
-- !query analysis
@@ -217,6 +273,14 @@ Project [typeof(coalesce(cast(st_geogfromwkb(wkb#x) as geography(any)), cast(st_
217273
+- Relation spark_catalog.default.geodata[wkb#x] parquet
218274

219275

276+
-- !query
277+
SELECT typeof(coalesce(ST_GeomFromWKB(wkb), ST_GeomFromWKB(wkb)::GEOMETRY(ANY))) FROM geodata
278+
-- !query analysis
279+
Project [typeof(coalesce(cast(st_geomfromwkb(wkb#x) as geometry(any)), cast(st_geomfromwkb(wkb#x) as geometry(any)))) AS typeof(coalesce(st_geomfromwkb(wkb), CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY))))#x]
280+
+- SubqueryAlias spark_catalog.default.geodata
281+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
282+
283+
220284
-- !query
221285
SELECT typeof(IF(wkb IS NOT NULL, ST_GeogFromWKB(wkb)::GEOGRAPHY(ANY), ST_GeogFromWKB(wkb))) FROM geodata
222286
-- !query analysis
@@ -225,6 +289,14 @@ Project [typeof(if (isnotnull(wkb#x)) cast(st_geogfromwkb(wkb#x) as geography(an
225289
+- Relation spark_catalog.default.geodata[wkb#x] parquet
226290

227291

292+
-- !query
293+
SELECT typeof(IF(wkb IS NOT NULL, ST_GeomFromWKB(wkb)::GEOMETRY(ANY), ST_GeomFromWKB(wkb))) FROM geodata
294+
-- !query analysis
295+
Project [typeof(if (isnotnull(wkb#x)) cast(st_geomfromwkb(wkb#x) as geometry(any)) else cast(st_geomfromwkb(wkb#x) as geometry(any))) AS typeof((IF((wkb IS NOT NULL), CAST(st_geomfromwkb(wkb) AS GEOMETRY(ANY)), st_geomfromwkb(wkb))))#x]
296+
+- SubqueryAlias spark_catalog.default.geodata
297+
+- Relation spark_catalog.default.geodata[wkb#x] parquet
298+
299+
228300
-- !query
229301
SELECT hex(ST_AsBinary(ST_GeogFromWKB(X'0101000000000000000000f03f0000000000000040'))) AS result
230302
-- !query analysis

0 commit comments

Comments
 (0)