From 215ceae556699aa1012d8811ba51a7f8e7c31423 Mon Sep 17 00:00:00 2001 From: Themis Valtinos <73662635+themisvaltinos@users.noreply.github.com> Date: Fri, 20 Jun 2025 13:33:06 +0300 Subject: [PATCH 1/3] Fix(mssql): Properly quote table and views when dropping in mssql --- sqlmesh/core/engine_adapter/mssql.py | 13 +++++++++-- tests/core/engine_adapter/test_mssql.py | 30 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/sqlmesh/core/engine_adapter/mssql.py b/sqlmesh/core/engine_adapter/mssql.py index 40649f3c2d..da33d28b09 100644 --- a/sqlmesh/core/engine_adapter/mssql.py +++ b/sqlmesh/core/engine_adapter/mssql.py @@ -172,15 +172,24 @@ def drop_schema( if cascade: objects = self._get_data_objects(schema_name) for obj in objects: + # Build properly quoted table for MSSQL using square brackets when needed + object_name = ".".join( + [ + exp.to_identifier(obj.schema_name).sql(self.dialect), + exp.to_identifier(obj.name).sql(self.dialect), + ] + ) + object_table = exp.to_table(object_name, dialect=self.dialect) + # _get_data_objects is catalog-specific, so these can't accidentally drop view/tables in another catalog if obj.type == DataObjectType.VIEW: self.drop_view( - ".".join([obj.schema_name, obj.name]), + object_table, ignore_if_not_exists=ignore_if_not_exists, ) else: self.drop_table( - ".".join([obj.schema_name, obj.name]), + object_table, exists=ignore_if_not_exists, ) super().drop_schema(schema_name, ignore_if_not_exists=ignore_if_not_exists, cascade=False) diff --git a/tests/core/engine_adapter/test_mssql.py b/tests/core/engine_adapter/test_mssql.py index 939d26a95d..beeaa59c89 100644 --- a/tests/core/engine_adapter/test_mssql.py +++ b/tests/core/engine_adapter/test_mssql.py @@ -655,6 +655,36 @@ def test_drop_schema(make_mocked_engine_adapter: t.Callable): ] +def test_drop_schema_with_special_identifiers(make_mocked_engine_adapter: t.Callable): + adapter = make_mocked_engine_adapter(MSSQLEngineAdapter) + + adapter._get_data_objects = mock.Mock() + adapter._get_data_objects.return_value = [ + DataObject( + catalog="test_catalog", + schema="test schema", # Schema with space + name="test view", # Object with space + type=DataObjectType.from_str("VIEW"), + ), + DataObject( + catalog="test_catalog", + schema="test schema", + name="test table", # Table with space + type=DataObjectType.from_str("TABLE"), + ), + ] + + schema_name = exp.to_table("[test schema]", dialect="tsql") + adapter.drop_schema(schema_name, cascade=True) + + # Validate that names with spaces/special chars are properly quoted with square brackets + assert to_sql_calls(adapter) == [ + """DROP VIEW IF EXISTS [test schema].[test view];""", + """DROP TABLE IF EXISTS [test schema].[test table];""", + """DROP SCHEMA IF EXISTS [test schema];""", + ] + + def test_df_dates(make_mocked_engine_adapter: t.Callable): adapter = make_mocked_engine_adapter(MSSQLEngineAdapter) From 2dacc34a670b642ddd704d292a3cd46c7d65732c Mon Sep 17 00:00:00 2001 From: Themis Valtinos <73662635+themisvaltinos@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:29:23 +0300 Subject: [PATCH 2/3] use table_ instead Co-authored-by: Jo <46752250+georgesittas@users.noreply.github.com> --- sqlmesh/core/engine_adapter/mssql.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/sqlmesh/core/engine_adapter/mssql.py b/sqlmesh/core/engine_adapter/mssql.py index da33d28b09..07e3df5868 100644 --- a/sqlmesh/core/engine_adapter/mssql.py +++ b/sqlmesh/core/engine_adapter/mssql.py @@ -173,13 +173,7 @@ def drop_schema( objects = self._get_data_objects(schema_name) for obj in objects: # Build properly quoted table for MSSQL using square brackets when needed - object_name = ".".join( - [ - exp.to_identifier(obj.schema_name).sql(self.dialect), - exp.to_identifier(obj.name).sql(self.dialect), - ] - ) - object_table = exp.to_table(object_name, dialect=self.dialect) + object_name = exp.table_(obj.name, obj.schema_name) # _get_data_objects is catalog-specific, so these can't accidentally drop view/tables in another catalog if obj.type == DataObjectType.VIEW: From f27089fc55bd544d67832a0e24a95d93a4aa0c33 Mon Sep 17 00:00:00 2001 From: Themis Valtinos <73662635+themisvaltinos@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:36:25 +0300 Subject: [PATCH 3/3] fix correct name --- sqlmesh/core/engine_adapter/mssql.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sqlmesh/core/engine_adapter/mssql.py b/sqlmesh/core/engine_adapter/mssql.py index 07e3df5868..88b3f51ed3 100644 --- a/sqlmesh/core/engine_adapter/mssql.py +++ b/sqlmesh/core/engine_adapter/mssql.py @@ -173,7 +173,7 @@ def drop_schema( objects = self._get_data_objects(schema_name) for obj in objects: # Build properly quoted table for MSSQL using square brackets when needed - object_name = exp.table_(obj.name, obj.schema_name) + object_table = exp.table_(obj.name, obj.schema_name) # _get_data_objects is catalog-specific, so these can't accidentally drop view/tables in another catalog if obj.type == DataObjectType.VIEW: