From 3766a734fc1574507898060d514b70c263045073 Mon Sep 17 00:00:00 2001 From: arvis108 Date: Fri, 12 Sep 2025 14:22:39 +0300 Subject: [PATCH 1/2] Removed aggressive datetime parsing --- mssql_python/cursor.py | 32 ---------------- tests/test_004_cursor.py | 83 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 32 deletions(-) diff --git a/mssql_python/cursor.py b/mssql_python/cursor.py index f387e055..78d2b747 100644 --- a/mssql_python/cursor.py +++ b/mssql_python/cursor.py @@ -376,38 +376,6 @@ def _map_sql_type(self, param, parameters_list, i, min_val=None, max_val=None): except ValueError: pass - - # Attempt to parse as date, datetime, datetime2, timestamp, smalldatetime or time - if self._parse_date(param): - parameters_list[i] = self._parse_date( - param - ) # Replace the parameter with the date object - return ( - ddbc_sql_const.SQL_DATE.value, - ddbc_sql_const.SQL_C_TYPE_DATE.value, - 10, - 0, - False, - ) - if self._parse_datetime(param): - parameters_list[i] = self._parse_datetime(param) - return ( - ddbc_sql_const.SQL_TIMESTAMP.value, - ddbc_sql_const.SQL_C_TYPE_TIMESTAMP.value, - 26, - 6, - False, - ) - if self._parse_time(param): - parameters_list[i] = self._parse_time(param) - return ( - ddbc_sql_const.SQL_TIME.value, - ddbc_sql_const.SQL_C_TYPE_TIME.value, - 8, - 0, - False, - ) - # String mapping logic here is_unicode = self._is_unicode_string(param) diff --git a/tests/test_004_cursor.py b/tests/test_004_cursor.py index 07b75497..38832131 100644 --- a/tests/test_004_cursor.py +++ b/tests/test_004_cursor.py @@ -10661,6 +10661,89 @@ def test_decimal_separator_calculations(cursor, db_connection): # Cleanup cursor.execute("DROP TABLE IF EXISTS #pytest_decimal_calc_test") +def test_date_string_parameter_binding(cursor, db_connection): + """Verify that date-like strings are treated as strings in parameter binding""" + table_name = "#pytest_date_string" + try: + drop_table_if_exists(cursor, table_name) + cursor.execute(f""" + CREATE TABLE {table_name} ( + a_column VARCHAR(20) + ) + """) + cursor.execute(f"INSERT INTO {table_name} (a_column) VALUES ('string1'), ('string2')") + db_connection.commit() + + date_str = "2025-08-12" + + # Should fail to match anything, since binding may treat it as DATE not VARCHAR + cursor.execute(f"SELECT a_column FROM {table_name} WHERE RIGHT(a_column, 10) = ?", (date_str,)) + rows = cursor.fetchall() + + assert rows == [], f"Expected no match for date-like string, got {rows}" + + except Exception as e: + pytest.fail(f"Date string parameter binding test failed: {e}") + finally: + drop_table_if_exists(cursor, table_name) + db_connection.commit() + +def test_time_string_parameter_binding(cursor, db_connection): + """Verify that time-like strings are treated as strings in parameter binding""" + table_name = "#pytest_time_string" + try: + drop_table_if_exists(cursor, table_name) + cursor.execute(f""" + CREATE TABLE {table_name} ( + time_col VARCHAR(22) + ) + """) + cursor.execute(f"INSERT INTO {table_name} (time_col) VALUES ('prefix_14:30:45_suffix')") + db_connection.commit() + + time_str = "14:30:45" + + # This should fail because '14:30:45' gets converted to TIME type + # and SQL Server can't compare TIME against VARCHAR with prefix/suffix + cursor.execute(f"SELECT time_col FROM {table_name} WHERE time_col = ?", (time_str,)) + rows = cursor.fetchall() + + assert rows == [], f"Expected no match for time-like string, got {rows}" + + except Exception as e: + pytest.fail(f"Time string parameter binding test failed: {e}") + finally: + drop_table_if_exists(cursor, table_name) + db_connection.commit() + +def test_datetime_string_parameter_binding(cursor, db_connection): + """Verify that datetime-like strings are treated as strings in parameter binding""" + table_name = "#pytest_datetime_string" + try: + drop_table_if_exists(cursor, table_name) + cursor.execute(f""" + CREATE TABLE {table_name} ( + datetime_col VARCHAR(33) + ) + """) + cursor.execute(f"INSERT INTO {table_name} (datetime_col) VALUES ('prefix_2025-08-12T14:30:45_suffix')") + db_connection.commit() + + datetime_str = "2025-08-12T14:30:45" + + # This should fail because '2025-08-12T14:30:45' gets converted to TIMESTAMP type + # and SQL Server can't compare TIMESTAMP against VARCHAR with prefix/suffix + cursor.execute(f"SELECT datetime_col FROM {table_name} WHERE datetime_col = ?", (datetime_str,)) + rows = cursor.fetchall() + + assert rows == [], f"Expected no match for datetime-like string, got {rows}" + + except Exception as e: + pytest.fail(f"Datetime string parameter binding test failed: {e}") + finally: + drop_table_if_exists(cursor, table_name) + db_connection.commit() + def test_close(db_connection): """Test closing the cursor""" try: From 519fc624b9e1943b8e29e2d6e06a49cb82676d9d Mon Sep 17 00:00:00 2001 From: arvis108 Date: Fri, 26 Sep 2025 08:28:51 +0300 Subject: [PATCH 2/2] Comment added back --- mssql_python/cursor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mssql_python/cursor.py b/mssql_python/cursor.py index 78d2b747..12d630d2 100644 --- a/mssql_python/cursor.py +++ b/mssql_python/cursor.py @@ -362,7 +362,7 @@ def _map_sql_type(self, param, parameters_list, i, min_val=None, max_val=None): 0, False, ) - + try: val = uuid.UUID(param) parameters_list[i] = val.bytes_le