Skip to content

Commit 8c5da5b

Browse files
committed
Restore basic support for spatial
1 parent 2d909d2 commit 8c5da5b

File tree

4 files changed

+35
-0
lines changed

4 files changed

+35
-0
lines changed

src/duckdb_py/native/python_objects.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ static bool KeyIsHashable(const LogicalType &type) {
444444
case LogicalTypeId::DATE:
445445
case LogicalTypeId::UUID:
446446
case LogicalTypeId::INTERVAL:
447+
case LogicalTypeId::GEOMETRY:
447448
return true;
448449
case LogicalTypeId::LIST:
449450
case LogicalTypeId::ARRAY:
@@ -511,6 +512,7 @@ py::object PythonObject::FromValue(const Value &val, const LogicalType &type,
511512
case LogicalTypeId::VARCHAR:
512513
return py::cast(StringValue::Get(val));
513514
case LogicalTypeId::BLOB:
515+
case LogicalTypeId::GEOMETRY:
514516
return py::bytes(StringValue::Get(val));
515517
case LogicalTypeId::BIT:
516518
return py::cast(Bit::ToString(StringValue::Get(val)));

src/duckdb_py/numpy/array_wrapper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ void ArrayWrapper::Append(idx_t current_offset, Vector &input, idx_t source_size
682682
may_have_null = ConvertColumn<string_t, PyObject *, duckdb_py_convert::StringConvert>(append_data);
683683
break;
684684
case LogicalTypeId::BLOB:
685+
case LogicalTypeId::GEOMETRY:
685686
may_have_null = ConvertColumn<string_t, PyObject *, duckdb_py_convert::BlobConvert>(append_data);
686687
break;
687688
case LogicalTypeId::BIT:

src/duckdb_py/numpy/raw_array_wrapper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ static idx_t GetNumpyTypeWidth(const LogicalType &type) {
6161
case LogicalTypeId::UUID:
6262
case LogicalTypeId::ARRAY:
6363
case LogicalTypeId::VARIANT:
64+
case LogicalTypeId::GEOMETRY:
6465
return sizeof(PyObject *);
6566
default:
6667
throw NotImplementedException("Unsupported type \"%s\" for DuckDB -> NumPy conversion", type.ToString());
@@ -124,6 +125,7 @@ string RawArrayWrapper::DuckDBToNumpyDtype(const LogicalType &type) {
124125
case LogicalTypeId::UUID:
125126
case LogicalTypeId::ARRAY:
126127
case LogicalTypeId::VARIANT:
128+
case LogicalTypeId::GEOMETRY:
127129
return "object";
128130
case LogicalTypeId::ENUM: {
129131
auto size = EnumType::GetSize(type);

tests/fast/types/test_geometry.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import pandas as pd
2+
3+
4+
class TestGeometry:
5+
def test_fetchall(self, duckdb_cursor):
6+
duckdb_cursor.execute("SELECT 'POINT(1 2)'::GEOMETRY AS geom")
7+
results = duckdb_cursor.fetchall()
8+
assert isinstance(results[0][0], bytes)
9+
10+
def test_fetchnumpy(self, duckdb_cursor):
11+
duckdb_cursor.execute("SELECT 'POINT(1 2)'::GEOMETRY AS geom")
12+
results = duckdb_cursor.fetchnumpy()
13+
assert isinstance(results["geom"][0], (bytes, bytearray))
14+
15+
def test_df(self, duckdb_cursor):
16+
duckdb_cursor.execute("SELECT 'POINT(1 2)'::GEOMETRY AS geom")
17+
df = duckdb_cursor.df()
18+
assert isinstance(df["geom"].iloc[0], (bytes, bytearray))
19+
20+
def test_null(self, duckdb_cursor):
21+
duckdb_cursor.execute("SELECT NULL::GEOMETRY AS geom")
22+
results = duckdb_cursor.fetchall()
23+
assert results[0][0] is None
24+
25+
def test_multiple_rows(self, duckdb_cursor):
26+
duckdb_cursor.execute("SELECT 'POINT(1 2)'::GEOMETRY AS geom UNION ALL SELECT NULL::GEOMETRY")
27+
df = duckdb_cursor.df()
28+
assert df.shape[0] == 2
29+
assert isinstance(df["geom"].iloc[0], (bytes, bytearray))
30+
assert pd.isna(df["geom"].iloc[1])

0 commit comments

Comments
 (0)