FIX: Removed aggressive datetime parsing by arvis108 · Pull Request #235 · microsoft/mssql-python

Work Item / Issue Reference

GitHub Issue: #234


Summary

Summary

This PR fixes a critical issue where string parameters were being automatically converted to datetime objects, causing failures in SQL queries that require string-to-string comparisons. The fix removes aggressive content-based datetime parsing from the _map_sql_type() method while preserving all existing functionality for actual datetime objects.

Problem

The mssql-python driver was failing on queries like:

cursor.execute("SELECT * FROM table WHERE RIGHT(column, 10) = ?", ('2025-08-12',))

This would throw datetime conversion errors because the driver was automatically trying to parse the string '2025-08-12' as a date object, even when it should remain a string for the RIGHT() function comparison.

Problematic Code (Before Fix):

if isinstance(param, str):
    # Attempt to parse as date, datetime, datetime2, timestamp, smalldatetime or time
    if self._parse_date(param):
        parameters_list[i] = self._parse_date(param)  # MUTATION!
        return (SQL_DATE, SQL_C_TYPE_DATE, 10, 0, False)
    if self._parse_datetime(param):
        parameters_list[i] = self._parse_datetime(param)  # MUTATION!
        return (SQL_TIMESTAMP, SQL_C_TYPE_TIMESTAMP, 26, 6, False)
    # ... more parsing attempts

Why This Was Wrong:

  1. Violated separation of concerns: Type mapping shouldn't do content parsing
  2. Unpredictable behavior: Same string could be treated differently in different contexts
  3. Data mutation: Modified user's parameter data without permission
  4. Against DB-API principles: Parameter binding should be based on Python type, not content

Solution

Approach: Follow PyMSSQL's proven type-based parameter mapping approach.

Key Changes:

  1. Removed automatic datetime parsing from _map_sql_type() for string parameters
  2. Strings now always map to VARCHAR/NVARCHAR based purely on Python type

Files Modified:

  • mssql_python/cursor.py: Simplified string parameter handling in _map_sql_type()
  • tests/test_004_cursor.py: Added test for string parameter behavior

Before vs After

Before (Failed):

date_str = '2025-08-12'
cursor.execute("SELECT * WHERE RIGHT(column, 10) = ?", (date_str,))  # DateTime conversion error

After (Works):

date_str = '2025-08-12'
cursor.execute("SELECT * WHERE RIGHT(column, 10) = ?", (date_str,))  # Works correctly