Skip to content

Commit 8e76809

Browse files
committed
fix: preserve geospatial result metadata and shapes
Signed-off-by: Cathleen Yan <58714163+cathleeny@users.noreply.github.com>
1 parent 76bb73a commit 8e76809

3 files changed

Lines changed: 32 additions & 7 deletions

File tree

‎src/databricks/sql/backend/thrift_backend.py‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -808,23 +808,31 @@ def _col_to_description(col, field=None, host_url=None):
808808

809809
@staticmethod
810810
def _hive_schema_to_description(t_table_schema, schema_bytes=None, host_url=None):
811+
arrow_fields = []
811812
field_dict = {}
812813
if pyarrow and schema_bytes:
813814
try:
814815
arrow_schema = pyarrow.ipc.read_schema(pyarrow.py_buffer(schema_bytes))
815-
# Build a dictionary mapping column names to fields
816-
for field in arrow_schema:
816+
arrow_fields = list(arrow_schema)
817+
# Retain a name fallback for malformed/partial schemas, but use
818+
# result-column position whenever it is available. SQL permits
819+
# duplicate aliases, for which a name lookup is ambiguous.
820+
for field in arrow_fields:
817821
field_dict[field.name] = field
818822
except Exception as e:
819823
logger.debug(f"Could not parse arrow schema: {e}")
820824

821825
return [
822826
ThriftDatabricksClient._col_to_description(
823827
col,
824-
field_dict.get(col.columnName) if field_dict else None,
828+
(
829+
arrow_fields[index]
830+
if index < len(arrow_fields)
831+
else field_dict.get(col.columnName)
832+
),
825833
host_url,
826834
)
827-
for col in t_table_schema.columns
835+
for index, col in enumerate(t_table_schema.columns)
828836
]
829837

830838
def _results_message_to_execute_response(

‎tests/unit/test_kernel_result_set.py‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ def test_fetchall_arrow_drains_all_batches(int_schema):
9595
assert rs.has_more_rows is False
9696

9797

98-
def test_geospatial_string_and_binary_values_keep_logical_type():
98+
@pytest.mark.parametrize("disable_pandas", [False, True])
99+
def test_geospatial_string_and_binary_values_keep_logical_type(disable_pandas):
99100
wkb = bytes.fromhex("0101000000000000000000F03F0000000000000040")
100101
geo_metadata = {
101102
b"databricks.type_name": b"GEOMETRY",
@@ -108,7 +109,8 @@ def test_geospatial_string_and_binary_values_keep_logical_type():
108109
schema=string_schema,
109110
)
110111
string_rows = _make_rs(
111-
_FakeKernelHandle(string_schema, [string_batch]), disable_pandas=True
112+
_FakeKernelHandle(string_schema, [string_batch]),
113+
disable_pandas=disable_pandas,
112114
).fetchall()
113115
assert [row[0] for row in string_rows] == ["SRID=4326;POINT(1 2)", None]
114116

@@ -124,10 +126,14 @@ def test_geospatial_string_and_binary_values_keep_logical_type():
124126
schema=binary_schema,
125127
)
126128
binary_rs = _make_rs(
127-
_FakeKernelHandle(binary_schema, [binary_batch]), disable_pandas=True
129+
_FakeKernelHandle(binary_schema, [binary_batch]),
130+
disable_pandas=disable_pandas,
128131
)
129132
assert binary_rs.description[0][1] == "geometry"
130133
binary_rows = binary_rs.fetchall()
134+
assert isinstance(binary_rows[0][0], dict)
135+
assert isinstance(binary_rows[0][0]["srid"], int)
136+
assert isinstance(binary_rows[0][0]["wkb"], bytes)
131137
assert binary_rows[0][0] == {"srid": 4326, "wkb": wkb}
132138
assert binary_rows[1][0] is None
133139

‎tests/unit/test_thrift_backend.py‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2627,6 +2627,17 @@ def test_hive_schema_to_description(self):
26272627
None, # No arrow schema
26282628
[("regular_col", "string")],
26292629
),
2630+
(
2631+
[
2632+
("g", ttypes.TTypeId.STRING_TYPE),
2633+
("g", ttypes.TTypeId.STRING_TYPE),
2634+
],
2635+
[
2636+
("g", {}),
2637+
("g", {b"Spark:DataType:SqlName": b"GEOMETRY(0)"}),
2638+
],
2639+
[("g", "string"), ("g", "geometry")],
2640+
),
26302641
]
26312642

26322643
for columns, arrow_fields, expected_types in test_cases:

0 commit comments

Comments
 (0)