From d355480ea1902598d53236ce6448b0f571ae09c1 Mon Sep 17 00:00:00 2001 From: varun-edachali-dbx Date: Mon, 30 Jun 2025 04:53:25 +0000 Subject: [PATCH 1/4] explicitly convert session conf values to str Signed-off-by: varun-edachali-dbx --- src/databricks/sql/backend/sea/backend.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/databricks/sql/backend/sea/backend.py b/src/databricks/sql/backend/sea/backend.py index 0c0400ae..639bb4eb 100644 --- a/src/databricks/sql/backend/sea/backend.py +++ b/src/databricks/sql/backend/sea/backend.py @@ -48,7 +48,7 @@ def _filter_session_configuration( - session_configuration: Optional[Dict[str, str]] + session_configuration: Optional[Dict[str, Any]] ) -> Optional[Dict[str, str]]: if not session_configuration: return None @@ -58,7 +58,7 @@ def _filter_session_configuration( for key, value in session_configuration.items(): if key.upper() in ALLOWED_SESSION_CONF_TO_DEFAULT_VALUES_MAP: - filtered_session_configuration[key.lower()] = value + filtered_session_configuration[key.lower()] = str(value) else: ignored_configs.add(key) @@ -181,7 +181,7 @@ def max_download_threads(self) -> int: def open_session( self, - session_configuration: Optional[Dict[str, str]], + session_configuration: Optional[Dict[str, Any]], catalog: Optional[str], schema: Optional[str], ) -> SessionId: From 51694b72b7d673809403d6356e85a36533e0445d Mon Sep 17 00:00:00 2001 From: varun-edachali-dbx Date: Mon, 30 Jun 2025 05:06:37 +0000 Subject: [PATCH 2/4] add unit test for filter_session_conf Signed-off-by: varun-edachali-dbx --- tests/unit/test_sea_backend.py | 64 ++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/tests/unit/test_sea_backend.py b/tests/unit/test_sea_backend.py index bc6768d2..79e96293 100644 --- a/tests/unit/test_sea_backend.py +++ b/tests/unit/test_sea_backend.py @@ -633,6 +633,70 @@ def test_utility_methods(self, sea_client): sea_client._extract_description_from_manifest(no_columns_manifest) is None ) + def test_filter_session_configuration_string_values(self): + """Test that _filter_session_configuration converts all values to strings.""" + session_config = { + "ANSI_MODE": True, + "statement_timeout": 3600, + "TIMEZONE": "UTC", + "enable_photon": False, + "MAX_FILE_PARTITION_BYTES": 128.5, + "unsupported_param": "value", + "ANOTHER_UNSUPPORTED": 42, + } + + result = _filter_session_configuration(session_config) + + # Verify result is not None + assert result is not None + + # Verify all returned values are strings + for key, value in result.items(): + assert isinstance(value, str), f"Value for key '{key}' is not a string: {type(value)}" + + # Verify specific conversions + expected_result = { + "ansi_mode": "True", # boolean True -> "True", key lowercased + "statement_timeout": "3600", # int -> "3600", key lowercased + "timezone": "UTC", # string -> "UTC", key lowercased + "enable_photon": "False", # boolean False -> "False", key lowercased + "max_file_partition_bytes": "128.5", # float -> "128.5", key lowercased + } + + assert result == expected_result + + # Test with None input + assert _filter_session_configuration(None) is None + + # Test with empty dict + assert _filter_session_configuration({}) is None + + # Test with only unsupported parameters + unsupported_config = { + "unsupported_param1": "value1", + "unsupported_param2": 123, + } + result = _filter_session_configuration(unsupported_config) + assert result == {} + + # Test case insensitivity for keys + case_insensitive_config = { + "ansi_mode": "false", # lowercase key + "STATEMENT_TIMEOUT": 7200, # uppercase key + "TiMeZoNe": "America/New_York", # mixed case key + } + result = _filter_session_configuration(case_insensitive_config) + expected_case_result = { + "ansi_mode": "false", + "statement_timeout": "7200", + "timezone": "America/New_York", + } + assert result == expected_case_result + + # Verify all values are strings in case insensitive test + for key, value in result.items(): + assert isinstance(value, str), f"Value for key '{key}' is not a string: {type(value)}" + def test_results_message_to_execute_response_is_staging_operation(self, sea_client): """Test that is_staging_operation is correctly set from manifest.is_volume_operation.""" # Test when is_volume_operation is True From e09de769df50dd1550a8a84691f91b47c8184f4c Mon Sep 17 00:00:00 2001 From: varun-edachali-dbx Date: Thu, 3 Jul 2025 14:00:08 +0530 Subject: [PATCH 3/4] re-introduce unit test for string values of session conf Signed-off-by: varun-edachali-dbx --- tests/unit/test_sea_backend.py | 68 ++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/tests/unit/test_sea_backend.py b/tests/unit/test_sea_backend.py index 7eae8e5a..cc9d8e98 100644 --- a/tests/unit/test_sea_backend.py +++ b/tests/unit/test_sea_backend.py @@ -621,6 +621,74 @@ def test_utility_methods(self, sea_client): assert description[1][1] == "INT" # type_code assert description[1][6] is False # null_ok + def test_filter_session_configuration_string_values(self): + """Test that _filter_session_configuration converts all values to strings.""" + session_config = { + "ANSI_MODE": True, + "statement_timeout": 3600, + "TIMEZONE": "UTC", + "enable_photon": False, + "MAX_FILE_PARTITION_BYTES": 128.5, + "unsupported_param": "value", + "ANOTHER_UNSUPPORTED": 42, + } + + result = _filter_session_configuration(session_config) + + # Verify result is not None + assert result is not None + + # Verify all returned values are strings + for key, value in result.items(): + assert isinstance( + value, str + ), f"Value for key '{key}' is not a string: {type(value)}" + + # Verify specific conversions + expected_result = { + "ansi_mode": "True", # boolean True -> "True", key lowercased + "statement_timeout": "3600", # int -> "3600", key lowercased + "timezone": "UTC", # string -> "UTC", key lowercased + "enable_photon": "False", # boolean False -> "False", key lowercased + "max_file_partition_bytes": "128.5", # float -> "128.5", key lowercased + } + + assert result == expected_result + + # Test with None input + assert _filter_session_configuration(None) is None + + # Test with empty dict + assert _filter_session_configuration({}) is None + + # Test with only unsupported parameters + unsupported_config = { + "unsupported_param1": "value1", + "unsupported_param2": 123, + } + result = _filter_session_configuration(unsupported_config) + assert result == {} + + # Test case insensitivity for keys + case_insensitive_config = { + "ansi_mode": "false", # lowercase key + "STATEMENT_TIMEOUT": 7200, # uppercase key + "TiMeZoNe": "America/New_York", # mixed case key + } + result = _filter_session_configuration(case_insensitive_config) + expected_case_result = { + "ansi_mode": "false", + "statement_timeout": "7200", + "timezone": "America/New_York", + } + assert result == expected_case_result + + # Verify all values are strings in case insensitive test + for key, value in result.items(): + assert isinstance( + value, str + ), f"Value for key '{key}' is not a string: {type(value)}" + def test_results_message_to_execute_response_is_staging_operation(self, sea_client): """Test that is_staging_operation is correctly set from manifest.is_volume_operation.""" # Test when is_volume_operation is True From e3b00e377176126025cd6c6df73b91897237e6b0 Mon Sep 17 00:00:00 2001 From: varun-edachali-dbx Date: Thu, 3 Jul 2025 14:14:34 +0530 Subject: [PATCH 4/4] ensure Dict return from _filter_session_conf Signed-off-by: varun-edachali-dbx --- src/databricks/sql/backend/sea/backend.py | 6 +++--- tests/unit/test_sea_backend.py | 7 ++----- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/databricks/sql/backend/sea/backend.py b/src/databricks/sql/backend/sea/backend.py index 07d5bb8f..9df67aba 100644 --- a/src/databricks/sql/backend/sea/backend.py +++ b/src/databricks/sql/backend/sea/backend.py @@ -48,10 +48,10 @@ def _filter_session_configuration( - session_configuration: Optional[Dict[str, Any]] -) -> Optional[Dict[str, str]]: + session_configuration: Optional[Dict[str, Any]], +) -> Dict[str, str]: if not session_configuration: - return None + return {} filtered_session_configuration = {} ignored_configs: Set[str] = set() diff --git a/tests/unit/test_sea_backend.py b/tests/unit/test_sea_backend.py index cc9d8e98..37ba339a 100644 --- a/tests/unit/test_sea_backend.py +++ b/tests/unit/test_sea_backend.py @@ -621,7 +621,7 @@ def test_utility_methods(self, sea_client): assert description[1][1] == "INT" # type_code assert description[1][6] is False # null_ok - def test_filter_session_configuration_string_values(self): + def test_filter_session_configuration(self): """Test that _filter_session_configuration converts all values to strings.""" session_config = { "ANSI_MODE": True, @@ -656,10 +656,7 @@ def test_filter_session_configuration_string_values(self): assert result == expected_result # Test with None input - assert _filter_session_configuration(None) is None - - # Test with empty dict - assert _filter_session_configuration({}) is None + assert _filter_session_configuration(None) == {} # Test with only unsupported parameters unsupported_config = {