FIX: NULL parameter type mapping for VARBINARY columns (#458)#466
FIX: NULL parameter type mapping for VARBINARY columns (#458)#466gargsaumya wants to merge 1 commit 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 479-489 479 sqlType = SQL_VARCHAR;
480 columnSize = 1;
481 decimalDigits = 0;
482 } else {
! 483 sqlType = describedType;
! 484 columnSize = describedSize;
! 485 decimalDigits = describedDigits;
486 }
487 }
488 dataPtr = nullptr;
489 strLenOrIndPtr = AllocateParamBuffer<SQLLEN>(paramBuffers);📋 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.h: 67.8%
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.__init__.py: 84.9%
mssql_python.cursor.py: 84.9%
mssql_python.connection.py: 85.1%🔗 Quick Links
|
e6bd5b5 to
03e7b4f
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.