Implement SQLGetTypeInfo - #152
Conversation
📊 Code Coverage Report
Diff CoverageDiff: main...HEAD, staged and unstaged changes
Summary
mssql-odbc/src/api/get_type_info.rs🔗 Quick Links |
There was a problem hiding this comment.
Pull request overview
Implements RPC-backed SQLGetTypeInfoW with validation, diagnostics, metadata renaming, and end-to-end coverage.
Changes:
- Executes
sp_datatype_info_100and exposes its fetchable result set. - Adds ODBC type constants, diagnostics, and parent ENV access.
- Adds unit and live integration tests.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
mssql-odbc/src/api/get_type_info.rs |
Implements type-info retrieval and validation. |
mssql-odbc/src/api/exports.rs |
Exports SQLGetTypeInfoW. |
mssql-odbc/src/api/mod.rs |
Registers the new module. |
mssql-odbc/src/api/odbc_types.rs |
Adds required type constants. |
mssql-odbc/src/api/sqlstate.rs |
Adds the HYC00 diagnostic. |
mssql-odbc/src/handles/dbc.rs |
Adds parent ENV access. |
mssql-odbc/tests/e2e/tests/get_type_info_test.cpp |
Tests observable type-info behavior. |
mssql-odbc/tests/e2e/CMakeLists.txt |
Registers the new test suite. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
mssql-odbc/src/api/get_type_info.rs:190
finish_executepublishesCURSOR_OPEN, clearsEXEC_STARTED, and releases the statement lock before these renames run. A concurrent call on the same STMT can therefore observe the catalog's unrenamed metadata, or close/reuse the statement and have this loop rename columns in the next result set. Commit the renamed metadata in the same locked state transition that publishes the result set (for example, letfinish_executeaccept a metadata transform) so the cursor never becomes visible before renaming.
rename_type_info_columns(stmt, is_2x_app);
mssql-odbc/src/api/get_type_info.rs:159
- The positional/named RPC shape is a stated parity requirement, but no test inspects it.
odbc2_app_omits_odbc_ver_and_remaps_dateonly reaches this branch and then asserts a disconnectedSQL_ERROR; it would still pass if@ODBCVerwere sent or@data_typewere named/wrongly typed. Extract the parameter construction into a pure helper and assert the ODBC 2.x and 3.x parameter names, types, and values. The live outcome-only test should also carry the requiredBenefits-from-mock-tds:note for the wire-level assertion it cannot make.
// `@ODBCVer` is named and sent only for 3.x applications (matching
// msodbcsql's `!IS2xAPP` guard).
let named = if is_2x_app {
None
} else {
Some(vec![RpcParameter::new(
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
mssql-odbc/src/api/get_type_info.rs:201
- These post-processing helpers swallow mutex-poison failures, so
SQLGetTypeInfoWcan return the successfulfinish_executestatus even though the required names/nullability were not applied. This also takes the statement lock twice and exposes partially post-processed metadata between the calls. Apply both mutations under one lock and propagate lock failure asSQL_ERRORrather than returningrc.
rename_type_info_columns(stmt, is_2x_app);
clear_type_info_nullable(stmt);
mssql-odbc/src/api/get_type_info.rs:172
- The disconnected
odbc2_app_omits_odbc_ver_and_remaps_datetest stops inclaim_connection, so it never observes thisnamed = Nonebranch or the RPC payload. The repository's ODBC testing guidance requires byte-level behavior hidden by live outcome tests to be pinned in Rust; extract RPC parameter construction into a testable helper (or add a mock-TDS seam) and assert that ODBC 2 omits@ODBCVerwhile ODBC 3 sends the named tinyint value.
let named = if is_2x_app {
None
} else {
Some(vec![RpcParameter::new(
Some("@ODBCVer".to_string()),
StatusFlags::NONE,
SqlType::TinyInt(Some(ODBC_VER_KATMAI)),
mssql-odbc/tests/e2e/tests/get_type_info_test.cpp:96
- The PR description explicitly lists the
ClearNullabledescriptor tweak as deferred, but this test andclear_type_info_nullableimplement and require that behavior. Either update the description/scope to include the nullable metadata change or remove this behavior if it is still meant to be deferred.
// The columns the ODBC spec defines as NOT NULL report SQL_NO_NULLS, matching
// msodbcsql's ClearNullable post-processing.
TEST_F(GetTypeInfoLiveTest, NotNullColumnsReportNoNulls) {
…; add invalid-then-valid recovery e2e test
Description
Implements
SQLGetTypeInfoWfor the mssql-odbc driver. It executes thesp_datatype_info_100catalog procedure as an RPC (matching the classic msodbcsql driver) and leaves the result
set open for
SQLFetch/SQLGetData, reusing the existing execute/fetch machinery.Behaviors, verified for parity against the msodbcsql source so the crate is a drop-in
replacement behind the same Driver Manager (mssql-python swap):
DataTypeargument before any I/O: unrecognized type →HY004, user-defined type →HYC00, active exec / open cursor →24000.@data_typesent positionally (SQLINT2);@ODBCVer = 3sent as a named parameter forODBC 3.x apps; 2.x apps omit it and receive the 2.x date/time id remap.
COLUMN_SIZE/FIXED_PREC_SCALE/AUTO_UNIQUE_VALUE) soSQLDescribeColreports the ODBC 3.x names identically.Supporting additions:
DbcHandle::parent_env()accessor,SQL_ALL_TYPES/SQL_TIMEconstants, and an
HYC00(ERR_OPTIONAL_FEATURE_NOT_IMPLEMENTED) diagnostic.Deferred (gated on infrastructure not yet in this driver), matching msodbcsql but scoped out:
_90/_170) — needs the negotiated serverversion plumbed to the ODBC layer;
_100is valid for all supported servers (2016+).ClearNullabledescriptor tweak — affectsSQLColAttribute(NULLABLE), not yet wired.sp_ddopenscrollable-cursor wrapper — no cursors yet (forward-only firehose).Note: retrieving type-info columns as native C types (e.g.
SQL_C_SSHORT) depends on thePhase-5
SQLGetDataconversion work; today the columns read back asSQL_C_CHAR/SQL_C_WCHAR.Tests: 5 unit tests (null handle,
HY004,HYC00, disconnected,24000) plus a live e2esuite (
get_type_info_test.cpp, registered in the e2e CMakeLists).Related Issues
https://sqlclientdrivers.visualstudio.com/DefaultCollection/mssql-rs/_workitems/edit/46406
Checklist
cargo bfmtpassescargo bclippypassescargo btestpasses