diff --git a/src/firebolt/common/statement_formatter.py b/src/firebolt/common/statement_formatter.py index d35da723dbe..91364f23867 100644 --- a/src/firebolt/common/statement_formatter.py +++ b/src/firebolt/common/statement_formatter.py @@ -75,7 +75,9 @@ def format_value(self, value: ParameterType) -> str: elif isinstance(value, datetime): if value.tzinfo is not None: value = value.astimezone(timezone.utc) - return f"'{value.strftime('%Y-%m-%d %H:%M:%S')}'" + # Keep fractional seconds; whole-second values render as before. + fmt = "%Y-%m-%d %H:%M:%S.%f" if value.microsecond else "%Y-%m-%d %H:%M:%S" + return f"'{value.strftime(fmt)}'" elif isinstance(value, date): return f"'{value.isoformat()}'" elif isinstance(value, bytes): diff --git a/tests/unit/common/test_typing_format.py b/tests/unit/common/test_typing_format.py index ea7273d1c83..3f3586f9c97 100644 --- a/tests/unit/common/test_typing_format.py +++ b/tests/unit/common/test_typing_format.py @@ -52,6 +52,11 @@ def formatter_v1() -> StatementFormatter: datetime(2022, 1, 10, 1, 1, 1, tzinfo=timezone(timedelta(hours=1))), "'2022-01-10 00:01:01'", ), + (datetime(2022, 1, 10, 1, 1, 1, 123456), "'2022-01-10 01:01:01.123456'"), + ( + datetime(2022, 1, 10, 1, 1, 1, 50, tzinfo=timezone(timedelta(hours=1))), + "'2022-01-10 00:01:01.000050'", + ), # List, tuple ([], "[]"), ([1, 2, 3], "[1, 2, 3]"), @@ -66,6 +71,17 @@ def test_format_value(formatter: StatementFormatter, value: str, result: str) -> assert formatter.format_value(value) == result, "Invalid format_value result" +def test_format_statement_keeps_datetime_fractional_seconds( + formatter: StatementFormatter, +) -> None: + """Truncating to whole seconds silently changes stored and compared values.""" + statement = parse("SELECT * FROM t WHERE ts = ?")[0] + assert ( + formatter.format_statement(statement, [datetime(2024, 2, 29, 1, 2, 3, 4)]) + == "SELECT * FROM t WHERE ts = '2024-02-29 01:02:03.000004'" + ) + + @mark.parametrize( "value,result", [ # Strings @@ -89,6 +105,11 @@ def test_format_value(formatter: StatementFormatter, value: str, result: str) -> datetime(2022, 1, 10, 1, 1, 1, tzinfo=timezone(timedelta(hours=1))), "'2022-01-10 00:01:01'", ), + (datetime(2022, 1, 10, 1, 1, 1, 123456), "'2022-01-10 01:01:01.123456'"), + ( + datetime(2022, 1, 10, 1, 1, 1, 50, tzinfo=timezone(timedelta(hours=1))), + "'2022-01-10 00:01:01.000050'", + ), # List, tuple ([], "[]"), ([1, 2, 3], "[1, 2, 3]"),