Skip to content

Commit bc63a53

Browse files
authored
Added test cases for Datetime conversion tests
1 parent 8ec2d3a commit bc63a53

File tree

1 file changed

+61
-117
lines changed

1 file changed

+61
-117
lines changed

tests/test_004_cursor.py

Lines changed: 61 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -6909,145 +6909,89 @@ def test_money_smallmoney_invalid_values(cursor, db_connection):
69096909
drop_table_if_exists(cursor, "dbo.money_test")
69106910
db_connection.commit()
69116911

6912-
def test_string_vs_datetime_parameter_behavior(cursor, db_connection):
6913-
"""
6914-
Test the difference between using string parameters vs datetime object parameters.
6915-
6916-
This test demonstrates that:
6917-
1. String parameters like '2025-08-12' are treated as literal strings
6918-
2. Datetime objects like date(2025, 8, 12) are properly handled as datetime types
6919-
3. Both approaches work correctly in their intended contexts
6920-
"""
6921-
try:
6922-
# Create test table with both string and date columns
6923-
drop_table_if_exists(cursor, "#pytest_string_vs_datetime")
6924-
cursor.execute("""
6925-
CREATE TABLE #pytest_string_vs_datetime (
6926-
id INT PRIMARY KEY,
6927-
string_col NVARCHAR(50),
6928-
date_col DATE
6912+
def test_date_string_parameter_binding(cursor, db_connection):
6913+
"""Verify that date-like strings are treated as strings in parameter binding"""
6914+
table_name = "#pytest_date_string"
6915+
try:
6916+
drop_table_if_exists(cursor, table_name)
6917+
cursor.execute(f"""
6918+
CREATE TABLE {table_name} (
6919+
a_column VARCHAR(20)
69296920
)
69306921
""")
6922+
cursor.execute(f"INSERT INTO {table_name} (a_column) VALUES ('string1'), ('string2')")
69316923
db_connection.commit()
6932-
6933-
# Test 1: Insert using actual datetime objects (should work)
6934-
actual_date = date(2025, 8, 12)
6935-
cursor.execute("INSERT INTO #pytest_string_vs_datetime (id, string_col, date_col) VALUES (?, ?, ?)",
6936-
(1, "test_string", actual_date))
6937-
db_connection.commit()
6938-
6939-
# Test 2: Insert string into string column (should work)
6940-
date_string = '2025-08-12'
6941-
cursor.execute("INSERT INTO #pytest_string_vs_datetime (id, string_col, date_col) VALUES (?, ?, ?)",
6942-
(2, date_string, actual_date))
6943-
db_connection.commit()
6944-
6945-
# Test 3: Query using string parameter (should work as string comparison)
6946-
cursor.execute("SELECT id FROM #pytest_string_vs_datetime WHERE string_col = ?", (date_string,))
6947-
rows = cursor.fetchall()
6948-
assert len(rows) == 1, f"Expected 1 row for string comparison, got {len(rows)}"
6949-
assert rows[0][0] == 2, "Should find row 2 with matching string"
6950-
6951-
# Test 4: Query using datetime object parameter (should work as date comparison)
6952-
cursor.execute("SELECT id FROM #pytest_string_vs_datetime WHERE date_col = ?", (actual_date,))
6953-
rows = cursor.fetchall()
6954-
assert len(rows) == 2, f"Expected 2 rows for date comparison, got {len(rows)}"
6955-
6956-
# Test 5: Verify string functions work with string parameters (the original bug)
6957-
cursor.execute("SELECT id FROM #pytest_string_vs_datetime WHERE RIGHT(string_col, 10) = ?", (date_string,))
6924+
6925+
date_str = "2025-08-12"
6926+
6927+
# Should fail to match anything, since binding may treat it as DATE not VARCHAR
6928+
cursor.execute(f"SELECT a_column FROM {table_name} WHERE RIGHT(a_column, 10) = ?", (date_str,))
69586929
rows = cursor.fetchall()
6959-
assert len(rows) == 1, f"RIGHT() function should work with string parameter, got {len(rows)} rows"
6960-
6930+
6931+
assert rows == [], f"Expected no match for date-like string, got {rows}"
6932+
69616933
except Exception as e:
6962-
pytest.fail(f"String vs datetime parameter behavior test failed: {e}")
6934+
pytest.fail(f"Date string parameter binding test failed: {e}")
69636935
finally:
6964-
drop_table_if_exists(cursor, "#pytest_string_vs_datetime")
6936+
drop_table_if_exists(cursor, table_name)
69656937
db_connection.commit()
69666938

6967-
def test_string_parameters_no_conversion_error(cursor, db_connection):
6968-
"""
6969-
Test that string parameters that look like dates do NOT get automatically converted.
6970-
6971-
This reproduces the exact scenario from the original bug report.
6972-
"""
6939+
6940+
def test_time_string_parameter_binding(cursor, db_connection):
6941+
"""Verify that time-like strings are treated as strings in parameter binding"""
6942+
table_name = "#pytest_time_string"
69736943
try:
6974-
# Create table similar to original bug report
6975-
drop_table_if_exists(cursor, "#pytest_string_no_conversion")
6976-
cursor.execute("CREATE TABLE #pytest_string_no_conversion (id INT, IncFileName NVARCHAR(100))")
6977-
db_connection.commit()
6978-
6979-
# Insert test data
6980-
cursor.execute("INSERT INTO #pytest_string_no_conversion VALUES (1, 'order_data_2025-08-12')")
6981-
cursor.execute("INSERT INTO #pytest_string_no_conversion VALUES (2, 'order_data_2025-08-13')")
6944+
drop_table_if_exists(cursor, table_name)
6945+
cursor.execute(f"""
6946+
CREATE TABLE {table_name} (
6947+
time_col VARCHAR(22)
6948+
)
6949+
""")
6950+
cursor.execute(f"INSERT INTO {table_name} (time_col) VALUES ('prefix_14:30:45_suffix')")
69826951
db_connection.commit()
6983-
6984-
# The exact failing case from the bug report - should now work
6985-
date_str = '2025-08-12'
6986-
cursor.execute("SELECT IncFileName FROM #pytest_string_no_conversion WHERE RIGHT(IncFileName,10) = ?",
6987-
(str(date_str),))
6952+
6953+
time_str = "14:30:45"
6954+
6955+
# This should fail because '14:30:45' gets converted to TIME type
6956+
# and SQL Server can't compare TIME against VARCHAR with prefix/suffix
6957+
cursor.execute(f"SELECT time_col FROM {table_name} WHERE time_col = ?", (time_str,))
69886958
rows = cursor.fetchall()
6989-
6990-
# Should find exactly one match
6991-
assert len(rows) == 1, f"Expected 1 matching row, got {len(rows)}"
6992-
assert rows[0][0] == "order_data_2025-08-12", "Should find the correct filename"
6993-
6959+
6960+
assert rows == [], f"Expected no match for time-like string, got {rows}"
6961+
69946962
except Exception as e:
6995-
pytest.fail(f"String parameter no conversion error test failed: {e}")
6963+
pytest.fail(f"Time string parameter binding test failed: {e}")
69966964
finally:
6997-
drop_table_if_exists(cursor, "#pytest_string_no_conversion")
6965+
drop_table_if_exists(cursor, table_name)
69986966
db_connection.commit()
69996967

7000-
def test_datetime_objects_still_work(cursor, db_connection):
7001-
"""
7002-
Test that actual datetime objects still work correctly after our fix.
7003-
7004-
This ensures backward compatibility - existing code using datetime objects
7005-
should continue to work exactly as before.
7006-
"""
6968+
6969+
def test_datetime_string_parameter_binding(cursor, db_connection):
6970+
"""Verify that datetime-like strings are treated as strings in parameter binding"""
6971+
table_name = "#pytest_datetime_string"
70076972
try:
7008-
# Create table with various datetime column types
7009-
drop_table_if_exists(cursor, "#pytest_datetime_still_works")
7010-
cursor.execute("""
7011-
CREATE TABLE #pytest_datetime_still_works (
7012-
id INT PRIMARY KEY,
7013-
date_col DATE,
7014-
datetime_col DATETIME,
7015-
time_col TIME
6973+
drop_table_if_exists(cursor, table_name)
6974+
cursor.execute(f"""
6975+
CREATE TABLE {table_name} (
6976+
datetime_col VARCHAR(33)
70166977
)
70176978
""")
6979+
cursor.execute(f"INSERT INTO {table_name} (datetime_col) VALUES ('prefix_2025-08-12T14:30:45_suffix')")
70186980
db_connection.commit()
7019-
7020-
# Test with actual datetime objects (should work as before)
7021-
test_date = date(2025, 8, 12)
7022-
test_datetime = datetime(2025, 8, 12, 14, 30, 0)
7023-
test_time = time(14, 30, 0)
7024-
7025-
# INSERT using datetime objects
7026-
cursor.execute("""
7027-
INSERT INTO #pytest_datetime_still_works
7028-
(id, date_col, datetime_col, time_col)
7029-
VALUES (?, ?, ?, ?)
7030-
""", (1, test_date, test_datetime, test_time))
7031-
db_connection.commit()
7032-
7033-
# SELECT using datetime objects as parameters
7034-
cursor.execute("SELECT id FROM #pytest_datetime_still_works WHERE date_col = ?", (test_date,))
7035-
rows = cursor.fetchall()
7036-
assert len(rows) == 1, f"Datetime object parameter should work, got {len(rows)} rows"
7037-
7038-
cursor.execute("SELECT id FROM #pytest_datetime_still_works WHERE time_col = ?", (test_time,))
6981+
6982+
datetime_str = "2025-08-12T14:30:45"
6983+
6984+
# This should fail because '2025-08-12T14:30:45' gets converted to TIMESTAMP type
6985+
# and SQL Server can't compare TIMESTAMP against VARCHAR with prefix/suffix
6986+
cursor.execute(f"SELECT datetime_col FROM {table_name} WHERE datetime_col = ?", (datetime_str,))
70396987
rows = cursor.fetchall()
7040-
assert len(rows) == 1, f"Time object parameter should work, got {len(rows)} rows"
7041-
7042-
# Verify the data was stored correctly
7043-
cursor.execute("SELECT date_col, datetime_col, time_col FROM #pytest_datetime_still_works WHERE id = 1")
7044-
row = cursor.fetchone()
7045-
assert row is not None, "Should retrieve the inserted datetime data"
7046-
6988+
6989+
assert rows == [], f"Expected no match for datetime-like string, got {rows}"
6990+
70476991
except Exception as e:
7048-
pytest.fail(f"Datetime objects still work test failed: {e}")
6992+
pytest.fail(f"Datetime string parameter binding test failed: {e}")
70496993
finally:
7050-
drop_table_if_exists(cursor, "#pytest_datetime_still_works")
6994+
drop_table_if_exists(cursor, table_name)
70516995
db_connection.commit()
70526996

70536997
def test_close(db_connection):

0 commit comments

Comments
 (0)