Skip to content

FEAT: Add spatial type support (geography, geometry, hierarchyid)#423

Open
dlevy-msft-sql wants to merge 1 commit intomicrosoft:mainfrom
dlevy-msft-sql:spatial-type-support
Open

FEAT: Add spatial type support (geography, geometry, hierarchyid)#423
dlevy-msft-sql wants to merge 1 commit intomicrosoft:mainfrom
dlevy-msft-sql:spatial-type-support

Conversation

@dlevy-msft-sql
Copy link
Contributor

Work Item / Issue Reference

GitHub Issue #352


Summary

Adds SQL_SS_UDT (-151) handling so geography, geometry, and hierarchyid columns are fetched as bytes instead of raising errors. These SQL Server CLR User-Defined Types all report as SQL_SS_UDT via ODBC and were previously unhandled in both the C++ binding layer and Python type maps.

Changes

File Change
ddbc_bindings.cpp Define SQL_SS_UDT constant; add case SQL_SS_UDT: fallthroughs to SQL_BINARY in SQLGetData_wrap, SQLBindColums, and FetchBatchData; separate calculateRowSize case with LOB-size fallback; include in LOB detection for FetchMany_wrap and FetchAll_wrap
constants.py Add SQL_SS_UDT = -151 to ConstantsDDBC enum
cursor.py Add SQL_SS_UDT -> SQL_C_BINARY in sql_to_c_type map; add SQL_SS_UDT -> bytes in sql_to_python_type map
test_017_spatial_types.py 37 tests covering geography, geometry, and hierarchyid: fetch paths (fetchone/fetchmany/fetchall/executemany), NULL handling, mixed columns, binary round-trips, output converters, cursor.description metadata, error cases

Testing

  • Built ddbc_bindings.cp313-arm64.pyd with 0 errors
  • Existing test suite: 639 passed, 1 pre-existing failure (unrelated test_no_segfault_on_gc WinError 50), 8 skipped
  • Spatial tests require live SQL Server connection with geography/geometry/hierarchyid support

@github-actions
Copy link

github-actions bot commented Feb 7, 2026

📊 Code Coverage Report

🔥 Diff Coverage

100%


🎯 Overall Coverage

76%


📈 Total Lines Covered: 5486 out of 7148
📁 Project: mssql-python


Diff Coverage

Diff: main...HEAD, staged and unstaged changes

  • mssql_python/constants.py (100%)
  • mssql_python/pybind/ddbc_bindings.cpp (100%)

Summary

  • Total: 13 lines
  • Missing: 0 lines
  • Coverage: 100%

📋 Files Needing Attention

📉 Files with overall lowest coverage (click to expand)
mssql_python.pybind.logger_bridge.hpp: 58.8%
mssql_python.pybind.logger_bridge.cpp: 59.2%
mssql_python.row.py: 66.2%
mssql_python.pybind.ddbc_bindings.cpp: 69.4%
mssql_python.pybind.ddbc_bindings.h: 69.7%
mssql_python.pybind.connection.connection.cpp: 75.3%
mssql_python.ddbc_bindings.py: 79.6%
mssql_python.pybind.connection.connection_pool.cpp: 79.6%
mssql_python.connection.py: 84.1%
mssql_python.cursor.py: 84.8%

🔗 Quick Links

⚙️ Build Summary 📋 Coverage Details

View Azure DevOps Build

Browse Full Coverage Report

@dlevy-msft-sql dlevy-msft-sql marked this pull request as ready for review February 8, 2026 01:21
Copilot AI review requested due to automatic review settings February 8, 2026 01:21
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds handling for SQL Server CLR user-defined spatial types (reported via ODBC as SQL_SS_UDT / -151) so geography, geometry, and hierarchyid can be fetched as bytes instead of raising “unsupported type” errors.

Changes:

  • Add SQL_SS_UDT support in the native ODBC fetch/bind paths by treating it like binary data (including LOB/streaming detection).
  • Extend Python type mappings so SQL_SS_UDT maps to SQL_C_BINARY and bytes (including cursor.description type codes).
  • Add a comprehensive spatial-types test suite covering fetch methods, NULLs, metadata, converters, and error cases.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
mssql_python/pybind/ddbc_bindings.cpp Handles SQL_SS_UDT in SQLGetData, batch binding, row-size calculation, and LOB detection to fetch spatial UDTs as binary.
mssql_python/constants.py Introduces SQL_SS_UDT = -151 in ConstantsDDBC.
mssql_python/cursor.py Maps SQL_SS_UDT to SQL_C_BINARY for binding and to bytes for cursor.description type mapping.
tests/test_017_spatial_types.py Adds test coverage for geography/geometry/hierarchyid fetch behaviors and related metadata/converter scenarios.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@dlevy-msft-sql
Copy link
Contributor Author

Thanks for the review — both comments were valid and have been fixed in the amended commit:

Comment 1 — Unused ConstantsDDBC import in test file: Fixed. Removed the unused import from test_017_spatial_types.py.

Comment 2 — SQL_SS_UDT missing from SQLTypes.get_valid_types(): Fixed. Added ConstantsDDBC.SQL_SS_UDT.value to the valid-types set so cursor.setinputsizes() will accept SQL_SS_UDT as a valid type code.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@dlevy-msft-sql dlevy-msft-sql force-pushed the spatial-type-support branch 2 times, most recently from 1d85de4 to 8088d9c Compare February 8, 2026 02:50
Add SQL_SS_UDT (-151) handling so geography, geometry, and hierarchyid
columns are fetched as bytes instead of raising errors.

C++ changes (ddbc_bindings.cpp):
- Define SQL_SS_UDT constant
- Add case fallthroughs to SQL_BINARY in SQLGetData_wrap, SQLBindColums,
  and FetchBatchData
- Separate calculateRowSize case with LOB-size fallback
- Include SQL_SS_UDT in LOB detection for FetchMany_wrap and FetchAll_wrap

Python changes:
- constants.py: SQL_SS_UDT = -151 in ConstantsDDBC enum
- cursor.py: SQL_SS_UDT -> SQL_C_BINARY in sql_to_c_type map
- cursor.py: SQL_SS_UDT -> bytes in sql_to_python_type map

Tests:
- 37 tests covering all three UDT types (geography, geometry, hierarchyid)
- Fetch paths: fetchone, fetchmany, fetchall, executemany
- NULL handling, mixed columns, binary round-trips, error cases
- Output converter and cursor.description metadata verification
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant