FIX: NULL parameter type mapping for VARBINARY columns (#458)#466
FIX: NULL parameter type mapping for VARBINARY columns (#458)#466gargsaumya merged 5 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes a bug (issue #458) where inserting a Python None into a VARBINARY column via a bound parameter would raise an implicit conversion error from varchar to varbinary. The root cause was that the _map_sql_type function mapped None parameters to SQL_VARCHAR, causing the ODBC driver to assume a varchar type. The fix changes this to SQL_UNKNOWN_TYPE (value 0), which triggers the C++ layer (in the SQL_C_DEFAULT handler) to call SQLDescribeParam to determine the actual target column type, allowing correct NULL binding for any column type.
Changes:
- Updated
_map_sql_typeincursor.pyto useSQL_UNKNOWN_TYPEinstead ofSQL_VARCHARwhen binding aNone(NULL) parameter, enabling the driver to infer the correct target column type viaSQLDescribeParam.
Comments suppressed due to low confidence (1)
mssql_python/cursor.py:400
- No test covers the exact bug scenario from issue #458: calling
execute('insert into bytestest values (?)', None)withNoneas a single bound parameter to a VARBINARY column. The existingtest_varbinarymax_insert_fetch_nullusesCAST(NULL AS VARBINARY(MAX))as a SQL literal rather than a PythonNoneparameter binding, andtest_only_null_and_empty_binaryusesexecutemanywhere the column type is inferred from non-nullbytesvalues in the same column. A test that specifically exercisesexecutewith a standaloneNoneparameter against a VARBINARY column (the regression case from the bug report) should be added to prevent future regressions.
if param is None:
logger.debug("_map_sql_type: NULL parameter - index=%d", i)
return (
ddbc_sql_const.SQL_UNKNOWN_TYPE.value,
ddbc_sql_const.SQL_C_DEFAULT.value,
1,
0,
False,
)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
4904d97 to
e6bd5b5
Compare
📊 Code Coverage Report
Diff CoverageDiff: main...HEAD, staged and unstaged changes
Summary
mssql_python/pybind/ddbc_bindings.cppLines 481-491 481 sqlType = SQL_VARCHAR;
482 columnSize = 1;
483 decimalDigits = 0;
484 } else {
! 485 sqlType = describedType;
! 486 columnSize = describedSize;
! 487 decimalDigits = describedDigits;
488 }
489 }
490 dataPtr = nullptr;
491 strLenOrIndPtr = AllocateParamBuffer<SQLLEN>(paramBuffers);📋 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: 67.8%
mssql_python.row.py: 70.5%
mssql_python.pybind.logger_bridge.hpp: 70.8%
mssql_python.pybind.connection.connection.cpp: 75.3%
mssql_python.__init__.py: 77.1%
mssql_python.ddbc_bindings.py: 79.6%
mssql_python.pybind.connection.connection_pool.cpp: 79.6%
mssql_python.connection.py: 85.2%
mssql_python.cursor.py: 85.6%🔗 Quick Links
|
e6bd5b5 to
03e7b4f
Compare
e98ee90 to
ec522d3
Compare
Work Item / Issue Reference
Summary
This pull request makes a targeted fix to the parameter type mapping logic for NULL values in the
mssql_python/cursor.pyfile. The change improves compatibility and prevents implicit conversion errors when executing queries with NULL parameters.Parameter mapping improvement:
_map_sql_typefunction to useSQL_UNKNOWN_TYPEinstead ofSQL_VARCHAR, allowing the driver to correctly determine the column type and avoid conversion errors.