| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
There was a problem hiding this comment.
Fixes a native executemany() array-binding correctness bug where fixed-width numeric parameters could leave earlier ODBC indicator slots uninitialized if a None (NULL) appeared later in the batch, leading to sporadic “0 rows inserted” outcomes with no exception.
Changes:
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| tests/test_004_cursor.py | Adds regression coverage for executemany() numeric batches where NULLs occur late in the parameter arrays. |
| mssql_python/pybind/ddbc_bindings.cpp | Ensures indicator arrays for fixed-width numeric parameter arrays are always allocated and fully initialized before SQLBindParameter/SQLExecuteMany. |
Sorry, something went wrong.
📊 Code Coverage Report
Diff CoverageDiff: main...HEAD, staged and unstaged changes
Summary
mssql_python/pybind/ddbc_bindings.cppLines 2253-2261 2253 LOG("BindParameterArray: Binding SQL_C_DOUBLE array - "
2254 "param_index=%d, count=%zu",
2255 paramIndex, paramSetSize);
2256 double* dataArray = AllocateParamBufferArray<double>(tempBuffers, paramSetSize);
! 2257 strLenOrIndArray = AllocateParamBufferArray<SQLLEN>(tempBuffers, paramSetSize);
2258 for (size_t i = 0; i < paramSetSize; ++i) {
2259 if (columnValues[i].is_none()) {
2260 dataArray[i] = 0;
2261 strLenOrIndArray[i] = SQL_NULL_DATA;Lines 2260-2268 2260 dataArray[i] = 0;
2261 strLenOrIndArray[i] = SQL_NULL_DATA;
2262 } else {
2263 dataArray[i] = columnValues[i].cast<double>();
! 2264 strLenOrIndArray[i] = 0;
2265 }
2266 }
2267 LOG("BindParameterArray: SQL_C_DOUBLE bound - "
2268 "param_index=%d",Lines 2309-2317 2309 "array - param_index=%d, count=%zu",
2310 paramIndex, paramSetSize);
2311 unsigned char* dataArray =
2312 AllocateParamBufferArray<unsigned char>(tempBuffers, paramSetSize);
! 2313 strLenOrIndArray = AllocateParamBufferArray<SQLLEN>(tempBuffers, paramSetSize);
2314 for (size_t i = 0; i < paramSetSize; ++i) {
2315 if (columnValues[i].is_none()) {
2316 dataArray[i] = 0;
2317 strLenOrIndArray[i] = SQL_NULL_DATA;📋 Files Needing Attention📉 Files with overall lowest coverage (click to expand)mssql_python.pybind.logger_bridge.cpp: 59.2%
mssql_python.pybind.ddbc_bindings.h: 59.9%
mssql_python.pybind.logger_bridge.hpp: 70.8%
mssql_python.pybind.ddbc_bindings.cpp: 76.3%
mssql_python.__init__.py: 77.6%
mssql_python.row.py: 77.6%
mssql_python.ddbc_bindings.py: 79.6%
mssql_python.pybind.connection.connection_pool.cpp: 81.4%
mssql_python.pybind.connection.connection.cpp: 83.7%
mssql_python.logging.py: 85.5%🔗 Quick Links
|
Sorry, something went wrong.
There was a problem hiding this comment.
Looks good to me. Only concern is the code coverage showing pretty less. Probably you need to modify the existing test to cover the new AllocateParamBufferArray allocation call.
Sorry, something went wrong.
### Work Item / Issue Reference > [AB#47087](https://sqlclientdrivers.visualstudio.com/c6d89619-62de-46a0-8b46-70b92a84d85e/_workitems/edit/47087) ------------------------------------------------------------------- ### Summary Release mssql-python v1.13.0. Version bump to 1.13.0. Updates `mssql_python/__init__.py`, `setup.py`, `PyPI_Description.md`, and the README "Important Note" section. Bundled `mssql_py_core` bumped from 0.1.7 to 0.1.8 (no source/API changes — dev-nightly to stable pin). #### Enhancements - **ODBC driver ships exclusively via `mssql-python-odbc` (Phase 2)** — The `libs/` fallback introduced in v1.12.0 has been removed. `mssql-python` now hard-depends on `mssql-python-odbc==18.6.2.1`; `pip install mssql-python` still pulls the driver package transparently. Smaller wheels; driver binaries managed independently (#693). - **Apache Arrow bulk copy** — New `Cursor.bulkcopy_arrow(table_name, source)` method for high-performance bulk loading from `pyarrow.Table` / `RecordBatch` / Arrow C Data Interface sources; classic `bulkcopy()` now raises `TypeError` for Arrow inputs and steers users to the new method (#665). - **`token_provider=` parameter for Azure Identity credentials** — `connect()` accepts any credential with a `.get_token(scope)` method (`DefaultAzureCredential`, `AzureCliCredential`, `ManagedIdentityCredential`, …). Mutually exclusive with `Authentication=` in the connection string (#603, issue #577). - **Identity-aware connection pooling with token-expiry refresh** — Pool now keys on security context, preventing cross-identity connection leaks; token acquisition deferred to pool-misses; connections with near-expiry tokens refreshed automatically (#660, issues #651, #659). #### Bug Fixes - **Silent zero-row `executemany` batches on late NULLs** — Fixed numeric array parameter binding paths (`TINYINT`/`SMALLINT`/`INT`/`FLOAT`) that left indicator slots uninitialized when a NULL appeared partway through the batch (#702, issue #670). - **`SQL_WVARCHAR` output converter applied as catch-all to non-string columns** — Fallback now gated on `str`/`bytes` mapped types (#692, issue #691). - **Integer-keyed output converters silently never fired** — `add_output_converter(SQL_DECIMAL, ...)` and other integer SQL type code keys now dispatch correctly (pyodbc parity) (#690, issue #684). - **`RecordBatchReader.Close()` for Arrow result sets** — `Cursor.arrow_reader()` now returns a wrapper whose `.close()` releases server-side resources and leaves the parent cursor usable (#644, issue #643). - **`AttributeError` in `Cursor.__del__` on partially-initialized cursor** — `__init__` sets `closed`/`hstmt` before any raise; `__del__` uses correct `sys.is_finalizing()` guard (#646, issue #642). #### Version Bump - `mssql_python/__init__.py`: `__version__ = "1.13.0"` - `setup.py`: `version="1.13.0"` - `PyPI_Description.md`: `## What's new in v1.13.0` section refreshed - `README.md`: "Important Note" updated for Phase 2 (no more `libs/` fallback, `mssql-python-odbc==18.6.2.1`)
| Back | FazBrowse Home | New Git URL |
Work Item / Issue Reference
Summary
Root cause
The affected numeric binding paths allocated the ODBC indicator array only after encountering the first NULL. Earlier rows then contained uninitialized indicators, which could be interpreted as data-at-execution markers and cause a batch to insert zero rows without an exception.
Validation