Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go/docs/snowflake.md
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ Examples:
`adbc.snowflake.statement.ingest_geo_type`
: **Values:** `geography`, `geometry`, or empty string. **Default:** empty string

Which Snowflake data type to use when ingesting columns of GeoArrow extension types (`geoarrow.wkb`, `geoarrow.wkt`). If empty, then it will be detected: if the SRID is 4326 and `edges:spherical` is set, then it will be ingested as GEOGRAPHY, else GEOMETRY. If explicitly set, the driver will use the specified type.
Which Snowflake data type to use when ingesting columns of GeoArrow extension types (`geoarrow.wkb`, `geoarrow.wkt`). If empty, the type is detected per column from the CRS metadata: columns with SRID 4326 (or no CRS at all) are ingested as GEOGRAPHY, columns with any other SRID as GEOMETRY (so the SRID survives the round trip), and `edges:spherical` combined with a non-4326 SRID is an error. Most GeoArrow producers (e.g. DuckDB, GeoPandas) emit a `crs` but no `edges` field, so detection does not require `edges:spherical` for WGS84 data. If explicitly set, the driver uses the specified type for all GeoArrow columns.

Can be set on the statement.

Expand Down
12 changes: 9 additions & 3 deletions go/statement.go
Original file line number Diff line number Diff line change
Expand Up @@ -740,9 +740,7 @@ func (opts *ingestOptions) resolveGeoType(fieldIndex int, fieldName string, extM
return opts.geoType, nil
}
srid, edges := extractSRIDFromMeta(extMeta)
if srid == 4326 && edges == "spherical" {
return "geography", nil
} else if edges == "spherical" {
if edges == "spherical" && srid != 0 && srid != 4326 {
// Snowflake GEOGRAPHY is always SRID 4326, so if the user
// specified spherical edges but a different SRID, we should
// error/ask them to explicitly set the geo type
Expand All @@ -751,6 +749,14 @@ func (opts *ingestOptions) resolveGeoType(fieldIndex int, fieldName string, extM
Code: adbc.StatusInvalidData,
}
}
// Missing CRS, EPSG:4326, or an unparsable CRS defaults to GEOGRAPHY, as
// documented above — most GeoArrow producers (e.g. DuckDB) emit a crs but
// no "edges" field, and requiring edges == "spherical" would silently
// demote WGS84 data to GEOMETRY. Only a concrete non-4326 SRID promotes
// the column so the SRID survives the round trip.
if srid == 0 || srid == 4326 {
return "geography", nil
}
return "geometry", nil
}

Expand Down
12 changes: 9 additions & 3 deletions go/statement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,13 @@ func TestExtractSRIDFromMeta(t *testing.T) {
func TestResolveGeoType(t *testing.T) {
opts := &ingestOptions{}

// EPSG:4326 without an "edges" field stays GEOGRAPHY: most GeoArrow
// producers (DuckDB, GeoPandas) emit a crs but no edges, and WGS84 data
// should not silently demote to GEOMETRY (matches the documented
// contract of resolveGeoType).
ty, err := opts.resolveGeoType(0, "geom", `{"crs":"EPSG:4326"}`)
assert.NoError(t, err)
assert.Equal(t, "geometry", ty)
assert.Equal(t, "geography", ty)

ty, err = opts.resolveGeoType(0, "geom", `{"crs":"EPSG:3857"}`)
assert.NoError(t, err)
Expand All @@ -237,13 +241,15 @@ func TestResolveGeoType(t *testing.T) {
_, err = opts.resolveGeoType(0, "geom", `{"crs":"EPSG:3857", "edges":"spherical"}`)
assert.ErrorContains(t, err, `field #1 ("geom") is a GeoArrow array with spherical edges`)

// Missing or empty CRS metadata also stays GEOGRAPHY per the documented
// default.
ty, err = opts.resolveGeoType(0, "geom", "")
assert.NoError(t, err)
assert.Equal(t, "geometry", ty)
assert.Equal(t, "geography", ty)

ty, err = opts.resolveGeoType(0, "geom", "{}")
assert.NoError(t, err)
assert.Equal(t, "geometry", ty)
assert.Equal(t, "geography", ty)

// explicit geoType should override CRS-derived default
opts.geoType = "geometry"
Expand Down
Loading