Repository: databricks/dbt-databricks
Pull request #975 (2025-03-22 00:07:33)

More macro cleanup and unit tests
<!---
  Include the number of the issue addressed by this PR above if applicable.

  Example:
    resolves #1234

  Please review our pull request review process in CONTRIBUTING.md before your proceed.
-->

### Description

Further macro testing, and minor macro refactoring to make things easier to test.

### Checklist

- [x] I have run this code in development and it appears to resolve the stated issue
- [x] This PR includes tests, or tests are not required/relevant for this PR
- [x] I have updated the `CHANGELOG.md` and added information about my change to the "dbt-databricks next" section.



Patch:
diff --git a/dbt/include/databricks/macros/adapters/catalog.sql b/dbt/include/databricks/macros/adapters/catalog.sql
index 4166bb72..5d02bf07 100644
--- a/dbt/include/databricks/macros/adapters/catalog.sql
+++ b/dbt/include/databricks/macros/adapters/catalog.sql
@@ -11,7 +11,7 @@ columns AS (
 {{ databricks__get_catalog_results_sql() }}
   {%- endset -%}
 
-  {{ return(run_query(query)) }}
+  {{ return(run_query_as(query, 'get_catalog')) }}
 {%- endmacro %}
 
 {% macro databricks__get_catalog_relations(information_schema, relations) -%}
@@ -27,7 +27,7 @@ columns AS (
 {{ databricks__get_catalog_results_sql() }}
   {%- endset -%}
 
-  {{ return(run_query(query)) }}
+  {{ return(run_query_as(query, 'get_catalog_relations')) }}
 {%- endmacro %}
 
 {% macro databricks__get_catalog_tables_sql(information_schema) -%}
diff --git a/dbt/include/databricks/macros/adapters/columns.sql b/dbt/include/databricks/macros/adapters/columns.sql
index e9f14068..7cce2e44 100644
--- a/dbt/include/databricks/macros/adapters/columns.sql
+++ b/dbt/include/databricks/macros/adapters/columns.sql
@@ -1,6 +1,6 @@
 
 {% macro get_columns_comments(relation) -%}
-  {{ return(run_query(get_columns_comments_sql(relation))) }}
+  {{ return(run_query_as(get_columns_comments_sql(relation), 'get_columns_comments')) }}
 {% endmacro %}
 
 {% macro get_columns_comments_sql(relation) %}
@@ -8,10 +8,8 @@ DESCRIBE TABLE {{ relation.render() }}
 {% endmacro %}
 
 {% macro get_columns_comments_via_information_schema(relation) -%}
-  {% call statement('repair_table', fetch_result=False) -%}
-    {{ repair_table_sql(relation) }}
-  {% endcall %}
-  {{ return(run_query(get_columns_comments_via_information_schema_sql(relation))) }}
+  {{ run_query_as(repair_table_sql(relation), 'repair_table', fetch_result=False) }}
+  {{ return(run_query_as(get_columns_comments_via_information_schema_sql(relation), 'get_columns_comments_via_information_schema')) }}
 {% endmacro %}
 
 {% macro repair_table_sql(relation) %}
@@ -35,18 +33,14 @@ WHERE
     {% if not relation.is_delta %}
       {{ exceptions.raise_compiler_error('Delta format required for dropping columns from tables') }}
     {% endif %}
-    {%- call statement('alter_relation_remove_columns') -%}
-      {{ drop_columns_sql(relation, remove_columns) }}
-    {%- endcall -%}
+    {{ run_query_as(drop_columns_sql(relation, remove_columns), 'alter_relation_remove_columns', fetch_result=False) }}
   {% endif %}
 
   {% if add_columns %}
     {% if not relation.is_delta %}
       {{ exceptions.raise_compiler_error('Delta format required for dropping columns from tables') }}
     {% endif %}
-    {%- call statement('alter_relation_add_columns') -%}
-      {{ add_columns_sql(relation, add_columns) }}
-    {%- endcall -%}
+    {{ run_query_as(add_columns_sql(relation, add_columns), 'alter_relation_add_columns', fetch_result=False) }}
   {% endif %}
 {% endmacro %}
 
diff --git a/dbt/include/databricks/macros/adapters/copy_into.sql b/dbt/include/databricks/macros/adapters/copy_into.sql
index f2c444cb..d3f97ddd 100644
--- a/dbt/include/databricks/macros/adapters/copy_into.sql
+++ b/dbt/include/databricks/macros/adapters/copy_into.sql
@@ -77,7 +77,5 @@
     {%- endif %}
   {% endset %}
 
-  {% do log("Running COPY INTO" ~ adapter.redact_credentials(query), info=True) %}
-  {% do run_query(query) %}
-
+  {{ run_query_as(query, 'copy_into', fetch_result=False) }}
 {% endmacro %}
diff --git a/dbt/include/databricks/macros/adapters/databricks_catalog.sql b/dbt/include/databricks/macros/adapters/databricks_catalog.sql
index b427ccfc..9e51b71f 100644
--- a/dbt/include/databricks/macros/adapters/databricks_catalog.sql
+++ b/dbt/include/databricks/macros/adapters/databricks_catalog.sql
@@ -3,18 +3,21 @@
 {% endmacro %}
 
 {% macro databricks__current_catalog() -%}
-  {% call statement('current_catalog', fetch_result=True) %}
-      select current_catalog()
-  {% endcall %}
-  {% do return(load_result('current_catalog').table) %}
+  {{ return(run_query_as(current_catalog_sql(), 'current_catalog')) }}
+{% endmacro %}
+
+{% macro current_catalog_sql() %}
+SELECT current_catalog()
 {% endmacro %}
 
 {% macro use_catalog(catalog) -%}
-  {{ return(adapter.dispatch('use_catalog', 'dbt')(catalog)) }}
+  {{ adapter.dispatch('use_catalog', 'dbt')(catalog) }}
 {% endmacro %}
 
 {% macro databricks__use_catalog(catalog) -%}
-  {% call statement() %}
-    use catalog {{ adapter.quote(catalog)|lower }}
-  {% endcall %}
+  {{ run_query_as(use_catalog_sql(catalog), 'use_catalog', fetch_result=False) }}
 {% endmacro %}
+
+{% macro use_catalog_sql(catalog) %}
+USE CATALOG {{ adapter.quote(catalog)|lower }}
+{% endmacro %}
\ No newline at end of file
diff --git a/dbt/include/databricks/macros/adapters/metadata.sql b/dbt/include/databricks/macros/adapters/metadata.sql
index 01abc648..78fda565 100644
--- a/dbt/include/databricks/macros/adapters/metadata.sql
+++ b/dbt/include/databricks/macros/adapters/metadata.sql
@@ -7,11 +7,11 @@
 {% endmacro %}
 
 {% macro databricks__show_table_extended(schema_relation) %}
-  {% call statement('show_table_extended', fetch_result=True) -%}
-    show table extended in {{ schema_relation.without_identifier()|lower }} like '{{ schema_relation.identifier|lower }}'
-  {% endcall %}
+  {{ return(run_query_as(show_table_extended_sql(schema_relation), 'show_table_extended')) }}
+{% endmacro %}
 
-  {% do return(load_result('show_table_extended').table) %}
+{% macro show_table_extended_sql(schema_relation) %}
+SHOW TABLE EXTENDED IN {{ schema_relation.without_identifier()|lower }} LIKE '{{ schema_relation.identifier|lower }}'
 {% endmacro %}
 
 {% macro show_tables(relation) %}
@@ -19,11 +19,11 @@
 {% endmacro %}
 
 {% macro databricks__show_tables(relation) %}
-  {% call statement('show_tables', fetch_result=True) -%}
-    show tables in {{ relation|lower }}
-  {% endcall %}
+  {{ return(run_query_as(show_tables_sql(relation), 'show_tables')) }}
+{% endmacro %}
 
-  {% do return(load_result('show_tables').table) %}
+{% macro show_tables_sql(relation) %}
+SHOW TABLES IN {{ relation.render() }}
 {% endmacro %}
 
 {% macro show_views(relation) %}
@@ -31,75 +31,73 @@
 {% endmacro %}
 
 {% macro databricks__show_views(relation) %}
-  {% call statement('show_views', fetch_result=True) -%}
-    show views in {{ relation|lower }}
-  {% endcall %}
+  {{ return(run_query_as(show_views_sql(relation), 'show_views')) }}
+{% endmacro %}
 
-  {% do return(load_result('show_views').table) %}
+{% macro show_views_sql(relation) %}
+SHOW VIEWS IN {{ relation.render() }}
 {% endmacro %}
 
 {% macro databricks__get_relation_last_modified(information_schema, relations) -%}
+  {{ return(run_query_as(get_relation_last_modified_sql(information_schema, relations), 'last_modified')) }}
+{% endmacro %}
 
-  {%- call statement('last_modified', fetch_result=True) -%}
-    {% if information_schema.is_hive_metastore() %}
-        {%- for relation in relations -%}
-            select '{{ relation.schema }}' as schema,
-                    '{{ relation.identifier }}' as identifier,
-                    max(timestamp) as last_modified,
-                    {{ current_timestamp() }} as snapshotted_at
-            from (describe history {{ relation.schema|lower }}.{{ relation.identifier|lower }})
-            {% if not loop.last %}
-            union all
-            {% endif %}
-        {%- endfor -%}
-    {% else %}
-        select table_schema as schema,
-               table_name as identifier,
-               last_altered as last_modified,
-               {{ current_timestamp() }} as snapshotted_at
-        from `system`.`information_schema`.`tables`
-        where table_catalog = '{{ information_schema.database|lower }}' and
-        (
-          {%- for relation in relations -%}
-            (table_schema = '{{ relation.schema|lower }}' and
-             table_name = '{{ relation.identifier|lower }}'){%- if not loop.last %} or {% endif -%}
-          {%- endfor -%}
-        )
-    {% endif %}
-  {%- endcall -%}
-
-  {{ return(load_result('last_modified')) }}
-
+{% macro get_relation_last_modified_sql(information_schema, relations) %}
+  {% if information_schema.is_hive_metastore() %}
+    {%- for relation in relations -%}
+SELECT
+  '{{ relation.schema }}' AS schema,
+  '{{ relation.identifier }}' AS identifier,
+  max(timestamp) AS last_modified,
+  {{ current_timestamp() }} AS snapshotted_at
+  FROM (DESCRIBE HISTORY {{ relation.schema|lower }}.{{ relation.identifier|lower }})
+      {% if not loop.last %}
+UNION ALL
+      {% endif %}
+    {%- endfor -%}
+  {% else %}
+SELECT
+  table_schema AS schema,
+  table_name AS identifier,
+  last_altered AS last_modified,
+  {{ current_timestamp() }} AS snapshotted_at
+FROM `system`.`information_schema`.`tables`
+WHERE table_catalog = '{{ information_schema.database|lower }}'
+  AND (
+    {%- for relation in relations -%}
+    (table_schema = '{{ relation.schema|lower }}' AND
+    table_name = '{{ relation.identifier|lower }}'){%- if not loop.last %} OR {% endif -%}
+    {%- endfor -%}
+  )
+  {% endif %}
 {% endmacro %}
 
 {% macro get_view_description(relation) %}
-  {% call statement('get_view_description', fetch_result=True) -%}
-    select *
-    from `system`.`information_schema`.`views`
-    where table_catalog = '{{ relation.database|lower }}'
-      and table_schema = '{{ relation.schema|lower }}'
-      and table_name = '{{ relation.identifier|lower }}'
-  {%- endcall -%}
+  {{ return(run_query_as(get_view_description_sql(relation), 'get_view_description')) }}
+{% endmacro %}
 
-  {% do return(load_result('get_view_description').table) %}
+{% macro get_view_description_sql(relation) %}
+SELECT *
+FROM `system`.`information_schema`.`views`
+WHERE table_catalog = '{{ relation.database|lower }}'
+  AND table_schema = '{{ relation.schema|lower }}'
+  AND table_name = '{{ relation.identifier|lower }}'
 {% endmacro %}
 
 {% macro get_uc_tables(relation) %}
-  {{ log("Fetching tables for: " ~ relation.render()) }}
-  {%- call statement('get_uc_tables', fetch_result=True) %}
-
-  select
-    table_name,
-    if(table_type in ('EXTERNAL', 'MANAGED', 'MANAGED_SHALLOW_CLONE', 'EXTERNAL_SHALLOW_CLONE'), 'table', lower(table_type)) as table_type,
-    lower(data_source_format) as file_format,
-    table_owner
-  from `system`.`information_schema`.`tables`
-  where table_catalog = '{{ relation.database|lower }}' 
-    and table_schema = '{{ relation.schema|lower }}'
-    {%- if relation.identifier %}
-    and table_name = '{{ relation.identifier|lower }}'
-    {% endif %}
-  {% endcall -%}
+  {{ return(run_query_as(get_uc_tables_sql(relation), 'get_uc_tables')) }}
+{% endmacro %}
 
-  {% do return(load_result('get_uc_tables').table) %}
+{% macro get_uc_tables_sql(relation) %}
+SELECT
+  table_name,
+  if(table_type IN ('EXTERNAL', 'MANAGED', 'MANAGED_SHALLOW_CLONE', 'EXTERNAL_SHALLOW_CLONE'), 'table', lower(table_type)) AS table_type,
+  lower(data_source_format) AS file_format,
+  table_owner
+FROM `system`.`information_schema`.`tables`
+WHERE table_catalog = '{{ relation.database|lower }}' 
+  AND table_schema = '{{ relation.schema|lower }}'
+  {%- if relation.identifier %}
+  AND table_name = '{{ relation.identifier|lower }}'
+  {% endif %}
 {% endmacro %}
\ No newline at end of file
diff --git a/dbt/include/databricks/macros/adapters/persist_docs.sql b/dbt/include/databricks/macros/adapters/persist_docs.sql
index 42357b3f..16b5e403 100644
--- a/dbt/include/databricks/macros/adapters/persist_docs.sql
+++ b/dbt/include/databricks/macros/adapters/persist_docs.sql
@@ -1,30 +1,32 @@
 {% macro databricks__alter_column_comment(relation, column_dict) %}
-  {% if config.get('file_format', default='delta') in ['delta', 'hudi'] %}
+  {% set file_format = config.get('file_format', default='delta') %}
+  {% if file_format in ['delta', 'hudi'] %}
     {% for column in column_dict.values() %}
       {% set comment = column['description'] %}
       {% set escaped_comment = comment | replace('\'', '\\\'') %}
-      {% set comment_query %}
-        COMMENT ON COLUMN {{ relation.render()|lower }}.{{ api.Column.get_name(column) }} IS '{{ escaped_comment }}';
-      {% endset %}
-      {% do run_query(comment_query) %}
+      {% set column_path = relation.render() ~ '.' ~ api.Column.get_name(column) %}
+      {{ run_query_as(comment_on_column_sql(column_path, escaped_comment), 'alter_column_comment', fetch_result=False) }}
     {% endfor %}
+  {% else %}
+    {{ log('WARNING - requested to update column comments, but file format ' ~ file_format ~ ' does not support that.') }}
   {% endif %}
 {% endmacro %}
 
-{% macro alter_table_comment(relation, model) %}
-  {% set comment_query %}
-    comment on table {{ relation.render()|lower }} is '{{ model.description | replace("'", "\\'") }}'
-  {% endset %}
-  {% do run_query(comment_query) %}
+{% macro comment_on_column_sql(column_path, escaped_comment) %}
+COMMENT ON COLUMN {{ column_path }} IS '{{ escaped_comment }}'
 {% endmacro %}
 
 {% macro databricks__persist_docs(relation, model, for_relation, for_columns) -%}
   {%- if for_relation and config.persist_relation_docs() and model.description %}
-    {% do alter_table_comment(relation, model) %}
+    {{ run_query_as(alter_relation_comment_sql(relation, model), 'alter_relation_comment', fetch_result=False) }}
   {% endif %}
   {% if for_columns and config.persist_column_docs() and model.columns %}
     {%- set existing_columns = adapter.get_columns_in_relation(relation) -%}
     {%- set columns_to_persist_docs = adapter.get_persist_doc_columns(existing_columns, model.columns) -%}
-    {% do alter_column_comment(relation, columns_to_persist_docs) %}
+    {{ alter_column_comment(relation, columns_to_persist_docs) }}
   {% endif %}
 {% endmacro %}
+
+{% macro alter_relation_comment_sql(relation, model) %}
+COMMENT ON {{ relation.type.upper() }} {{ relation.render() }} IS '{{ model.description | replace("'", "\\'") }}'
+{% endmacro %}
\ No newline at end of file
diff --git a/dbt/include/databricks/macros/etc/statement.sql b/dbt/include/databricks/macros/etc/statement.sql
index 9adec4f4..135aa824 100644
--- a/dbt/include/databricks/macros/etc/statement.sql
+++ b/dbt/include/databricks/macros/etc/statement.sql
@@ -28,4 +28,15 @@
       {% endcall %}
     {% endfor %}
   {% endif %}
+{% endmacro %}
+
+{# a user-friendly interface into statements #}
+{% macro run_query_as(sql, name, fetch_result=True) %}
+  {% call statement(name, fetch_result, auto_begin=False) %}
+    {{ sql }}
+  {% endcall %}
+
+  {% if fetch_result %}
+    {{ return(load_result(name).table) }}
+  {% endif %}
 {% endmacro %}
\ No newline at end of file


Test patch:
diff --git a/tests/unit/macros/adapters/test_catalog_macros.py b/tests/unit/macros/adapters/test_catalog_macros.py
index 80fe92d4..fd8fef34 100644
--- a/tests/unit/macros/adapters/test_catalog_macros.py
+++ b/tests/unit/macros/adapters/test_catalog_macros.py
@@ -135,15 +135,15 @@ class TestCatalogMacros(MacroTestBase):
 
         # Mock run_query to return a dummy result
         mock_result = Mock()
-        context["run_query"] = Mock(return_value=mock_result)
+        context["run_query_as"] = Mock(return_value=mock_result)
 
         self.run_macro_raw(
             template_bundle.template, "databricks__get_catalog", information_schema, schemas
         )
 
         # Verify run_query was called once and capture the SQL
-        context["run_query"].assert_called_once()
-        sql_query = context["run_query"].call_args[0][0]
+        context["run_query_as"].assert_called_once()
+        sql_query = context["run_query_as"].call_args[0][0]
 
         # Check complete SQL structure
         expected_sql = """
@@ -197,7 +197,6 @@ class TestCatalogMacros(MacroTestBase):
         """Test the get_catalog_relations macro with mocked run_query"""
         information_schema = {"database": "test_catalog"}
 
-        # Create mock relations
         relation1 = MagicMock()
         relation1.schema = "test_schema1"
         relation1.identifier = "test_table1"
@@ -208,9 +207,8 @@ class TestCatalogMacros(MacroTestBase):
 
         relations = [relation1, relation2]
 
-        # Mock run_query to return a dummy result
         mock_result = Mock()
-        context["run_query"] = Mock(return_value=mock_result)
+        context["run_query_as"] = Mock(return_value=mock_result)
 
         self.run_macro_raw(
             template_bundle.template,
@@ -219,9 +217,7 @@ class TestCatalogMacros(MacroTestBase):
             relations,
         )
 
-        # Verify run_query was called once and capture the SQL
-        context["run_query"].assert_called_once()
-        sql_query = context["run_query"].call_args[0][0]
+        sql_query = context["run_query_as"].call_args[0][0]
 
         # Check complete SQL structure
         expected_sql = """
diff --git a/tests/unit/macros/adapters/test_metadata_macros.py b/tests/unit/macros/adapters/test_metadata_macros.py
new file mode 100644
index 00000000..68e38269
--- /dev/null
+++ b/tests/unit/macros/adapters/test_metadata_macros.py
@@ -0,0 +1,208 @@
+from unittest.mock import Mock
+
+import pytest
+
+from tests.unit.macros.base import MacroTestBase
+
+
+class TestMetadataMacros(MacroTestBase):
+    @pytest.fixture(scope="class")
+    def template_name(self) -> str:
+        return "adapters/metadata.sql"
+
+    @pytest.fixture(scope="class")
+    def macro_folders_to_load(self) -> list:
+        return ["macros", "macros/adapters"]
+
+    @pytest.fixture
+    def mock_relation(self):
+        relation = Mock()
+        relation.database = "test_db"
+        relation.schema = "test_schema"
+        relation.identifier = "test_table"
+        relation.render = Mock(return_value="`test_db`.`test_schema`.`test_table`")
+
+        relation.without_identifier = Mock(return_value="`test_db`.`test_schema`")
+
+        return relation
+
+    @pytest.fixture
+    def mock_schema_relation(self):
+        relation = Mock()
+        relation.database = "test_db"
+        relation.schema = "test_schema"
+        relation.render = Mock(return_value="`test_db`.`test_schema`")
+        return relation
+
+    @pytest.fixture
+    def mock_information_schema(self):
+        info_schema = Mock()
+        info_schema.database = "test_db"
+        info_schema.is_hive_metastore = Mock(return_value=False)
+        return info_schema
+
+    @pytest.fixture
+    def mock_relations_list(self, mock_relation):
+        relation1 = Mock()
+        relation1.schema = "test_schema1"
+        relation1.identifier = "test_table1"
+
+        relation2 = Mock()
+        relation2.schema = "test_schema2"
+        relation2.identifier = "test_table2"
+
+        return [relation1, relation2]
+
+    def test_show_table_extended_sql(self, template_bundle, mock_relation):
+        """Test SQL generation for show_table_extended_sql"""
+        result = self.run_macro(template_bundle.template, "show_table_extended_sql", mock_relation)
+
+        expected_sql = "SHOW TABLE EXTENDED IN `test_db`.`test_schema` LIKE 'test_table'"
+        assert self.clean_sql(result) == self.clean_sql(expected_sql)
+
+    def test_show_tables_sql(self, template_bundle, mock_schema_relation):
+        """Test SQL generation for show_tables_sql"""
+        result = self.run_macro(template_bundle.template, "show_tables_sql", mock_schema_relation)
+
+        expected_sql = "SHOW TABLES IN `test_db`.`test_schema`"
+        assert self.clean_sql(result) == self.clean_sql(expected_sql)
+
+    def test_show_views_sql(self, template_bundle, mock_schema_relation):
+        """Test SQL generation for show_views_sql"""
+        result = self.run_macro(template_bundle.template, "show_views_sql", mock_schema_relation)
+
+        expected_sql = "SHOW VIEWS IN `test_db`.`test_schema`"
+        assert self.clean_sql(result) == self.clean_sql(expected_sql)
+
+    def test_get_relation_last_modified_sql_unity_catalog(
+        self, context, template_bundle, mock_information_schema, mock_relations_list
+    ):
+        """Test SQL generation for get_relation_last_modified_sql with Unity Catalog"""
+
+        context["current_timestamp"] = Mock(return_value="current_timestamp()")
+        mock_information_schema.is_hive_metastore.return_value = False
+
+        result = self.run_macro(
+            template_bundle.template,
+            "get_relation_last_modified_sql",
+            mock_information_schema,
+            mock_relations_list,
+        )
+
+        expected_sql = """
+            SELECT
+              table_schema AS schema,
+              table_name AS identifier,
+              last_altered AS last_modified,
+              current_timestamp() AS snapshotted_at
+            FROM `system`.`information_schema`.`tables`
+            WHERE table_catalog = 'test_db'
+              AND (
+                (table_schema = 'test_schema1' AND table_name = 'test_table1') OR
+                (table_schema = 'test_schema2' AND table_name = 'test_table2')
+              )
+        """
+        assert self.clean_sql(result) == self.clean_sql(expected_sql)
+
+    def test_get_relation_last_modified_sql_hive_metastore(
+        self, context, template_bundle, mock_information_schema, mock_relations_list
+    ):
+        """Test SQL generation for get_relation_last_modified_sql with Hive Metastore"""
+
+        context["current_timestamp"] = Mock(return_value="current_timestamp()")
+        mock_information_schema.is_hive_metastore.return_value = True
+
+        result = self.run_macro(
+            template_bundle.template,
+            "get_relation_last_modified_sql",
+            mock_information_schema,
+            mock_relations_list,
+        )
+
+        expected_sql = """
+            SELECT
+              'test_schema1' AS schema,
+              'test_table1' AS identifier,
+              max(timestamp) AS last_modified,
+              current_timestamp() AS snapshotted_at
+            FROM (DESCRIBE HISTORY test_schema1.test_table1)
+            UNION ALL
+            SELECT
+              'test_schema2' AS schema,
+              'test_table2' AS identifier,
+              max(timestamp) AS last_modified,
+              current_timestamp() AS snapshotted_at
+            FROM (DESCRIBE HISTORY test_schema2.test_table2)
+        """
+        assert self.clean_sql(result) == self.clean_sql(expected_sql)
+
+    def test_get_view_description_sql(self, template_bundle, mock_relation):
+        """Test SQL generation for get_view_description_sql"""
+        result = self.run_macro(template_bundle.template, "get_view_description_sql", mock_relation)
+
+        expected_sql = """
+            SELECT *
+            FROM `system`.`information_schema`.`views`
+            WHERE table_catalog = 'test_db'
+              AND table_schema = 'test_schema'
+              AND table_name = 'test_table'
+        """
+        assert self.clean_sql(result) == self.clean_sql(expected_sql)
+
+    def test_get_uc_tables_sql_with_identifier(self, template_bundle, mock_relation):
+        """Test SQL generation for get_uc_tables_sql with identifier"""
+        result = self.run_macro(template_bundle.template, "get_uc_tables_sql", mock_relation)
+
+        expected_sql = """
+            SELECT
+              table_name,
+              if(table_type IN ('EXTERNAL', 'MANAGED', 'MANAGED_SHALLOW_CLONE', 'EXTERNAL_SHALLOW_CLONE'), 'table', lower(table_type)) AS table_type,
+              lower(data_source_format) AS file_format,
+              table_owner
+            FROM `system`.`information_schema`.`tables`
+            WHERE table_catalog = 'test_db' 
+              AND table_schema = 'test_schema'
+              AND table_name = 'test_table'
+        """  # noqa
+        assert self.clean_sql(result) == self.clean_sql(expected_sql)
+
+    def test_get_uc_tables_sql_without_identifier(self, template_bundle, mock_schema_relation):
+        """Test SQL generation for get_uc_tables_sql without identifier"""
+        mock_schema_relation.identifier = None
+
+        result = self.run_macro(template_bundle.template, "get_uc_tables_sql", mock_schema_relation)
+
+        expected_sql = """
+            SELECT
+              table_name,
+              if(table_type IN ('EXTERNAL', 'MANAGED', 'MANAGED_SHALLOW_CLONE', 'EXTERNAL_SHALLOW_CLONE'), 'table', lower(table_type)) AS table_type,
+              lower(data_source_format) AS file_format,
+              table_owner
+            FROM `system`.`information_schema`.`tables`
+            WHERE table_catalog = 'test_db' 
+              AND table_schema = 'test_schema'
+        """  # noqa
+        assert self.clean_sql(result) == self.clean_sql(expected_sql)
+
+    def test_case_sensitivity(self, template_bundle):
+        """Test proper handling of case sensitivity with lowercase filters"""
+        relation = Mock()
+        relation.database = "TEST_DB"
+        relation.schema = "TEST_SCHEMA"
+        relation.identifier = "TEST_TABLE"
+        relation.render = Mock(return_value="`TEST_DB`.`TEST_SCHEMA`.`TEST_TABLE`")
+
+        result = self.run_macro(template_bundle.template, "get_uc_tables_sql", relation)
+
+        expected_sql = """
+            SELECT
+              table_name,
+              if(table_type IN ('EXTERNAL', 'MANAGED', 'MANAGED_SHALLOW_CLONE', 'EXTERNAL_SHALLOW_CLONE'), 'table', lower(table_type)) AS table_type,
+              lower(data_source_format) AS file_format,
+              table_owner
+            FROM `system`.`information_schema`.`tables`
+            WHERE table_catalog = 'test_db' 
+              AND table_schema = 'test_schema'
+              AND table_name = 'test_table'
+        """  # noqa
+        assert self.clean_sql(result) == self.clean_sql(expected_sql)
diff --git a/tests/unit/macros/adapters/test_persist_docs_macros.py b/tests/unit/macros/adapters/test_persist_docs_macros.py
new file mode 100644
index 00000000..12c94346
--- /dev/null
+++ b/tests/unit/macros/adapters/test_persist_docs_macros.py
@@ -0,0 +1,182 @@
+from unittest.mock import MagicMock, Mock
+
+import pytest
+
+from tests.unit.macros.base import MacroTestBase
+
+
+class TestPersistDocsMacros(MacroTestBase):
+    @pytest.fixture(scope="class")
+    def template_name(self) -> str:
+        return "adapters/persist_docs.sql"
+
+    @pytest.fixture(scope="class")
+    def macro_folders_to_load(self) -> list:
+        return ["macros", "macros/adapters"]
+
+    @pytest.fixture
+    def mock_relation(self):
+        relation = Mock()
+        relation.database = "test_db"
+        relation.schema = "test_schema"
+        relation.identifier = "test_table"
+        relation.render = Mock(return_value="`test_db`.`test_schema`.`test_table`")
+        relation.type = "table"
+        return relation
+
+    @pytest.fixture
+    def mock_model_with_description(self):
+        model = Mock()
+        model.description = "This is a test model"
+        return model
+
+    @pytest.fixture
+    def mock_model_with_columns(self):
+        model = Mock()
+        model.description = "Test model with columns"
+
+        column1 = {"name": "id", "description": "Primary key"}
+        column2 = {"name": "value", "description": "Contains 'quoted' text"}
+        model.columns = {"id": column1, "value": column2}
+
+        return model
+
+    def test_comment_on_column_sql(self, template_bundle):
+        column_path = "`test_db`.`test_schema`.`test_table`.id"
+        escaped_comment = "This is a column comment"
+
+        result = self.run_macro(
+            template_bundle.template, "comment_on_column_sql", column_path, escaped_comment
+        )
+
+        expected_sql = """
+            COMMENT ON COLUMN `test_db`.`test_schema`.`test_table`.id IS 'This is a column comment'
+        """
+        assert self.clean_sql(result) == self.clean_sql(expected_sql)
+
+    def test_alter_relation_comment_sql(
+        self, template_bundle, mock_relation, mock_model_with_description
+    ):
+        result = self.run_macro(
+            template_bundle.template,
+            "alter_relation_comment_sql",
+            mock_relation,
+            mock_model_with_description,
+        )
+
+        expected_sql = (
+            "COMMENT ON TABLE `test_db`.`test_schema`.`test_table` IS 'This is a test model'"
+        )
+        assert self.clean_sql(result) == self.clean_sql(expected_sql)
+
+    def test_alter_relation_comment_sql_with_quotes(self, template_bundle, mock_relation):
+        model = Mock()
+        model.description = "Model with 'quotes'"
+
+        result = self.run_macro(
+            template_bundle.template, "alter_relation_comment_sql", mock_relation, model
+        )
+
+        expected_sql = (
+            "COMMENT ON TABLE `test_db`.`test_schema`.`test_table` IS 'Model with \\'quotes\\''"
+        )
+        assert self.clean_sql(result) == self.clean_sql(expected_sql)
+
+    def test_alter_relation_comment_sql_view(self, template_bundle, mock_model_with_description):
+        view_relation = Mock()
+        view_relation.database = "test_db"
+        view_relation.schema = "test_schema"
+        view_relation.identifier = "test_view"
+        view_relation.render = Mock(return_value="`test_db`.`test_schema`.`test_view`")
+        view_relation.type = "view"
+
+        result = self.run_macro(
+            template_bundle.template,
+            "alter_relation_comment_sql",
+            view_relation,
+            mock_model_with_description,
+        )
+
+        expected_sql = (
+            "COMMENT ON VIEW `test_db`.`test_schema`.`test_view` IS 'This is a test model'"
+        )
+        assert self.clean_sql(result) == self.clean_sql(expected_sql)
+
+    def test_databricks__alter_column_comment_delta(
+        self, template_bundle, context, mock_relation, mock_model_with_columns
+    ):
+        context["config"] = Mock()
+        context["config"].get = Mock(return_value="delta")
+
+        context["api"] = MagicMock()
+        context["api"].Column.get_name = Mock(side_effect=lambda col: col["name"])
+
+        context["run_query_as"] = Mock()
+
+        self.run_macro_raw(
+            template_bundle.template,
+            "databricks__alter_column_comment",
+            mock_relation,
+            mock_model_with_columns.columns,
+        )
+
+        assert context["run_query_as"].call_count == 2
+
+        call_args_list = context["run_query_as"].call_args_list
+
+        first_call = call_args_list[0][0][0]
+        expected_first_sql = (
+            "COMMENT ON COLUMN `test_db`.`test_schema`.`test_table`.id IS 'Primary key'"
+        )
+        assert self.clean_sql(first_call) == self.clean_sql(expected_first_sql)
+
+        second_call = call_args_list[1][0][0]
+        expected_second_sql = """
+        COMMENT ON COLUMN `test_db`.`test_schema`.`test_table`.value IS 'Contains \\'quoted\\' text'
+"""
+        assert self.clean_sql(second_call) == self.clean_sql(expected_second_sql)
+
+    def test_databricks__alter_column_comment_unsupported_format(
+        self, template_bundle, context, mock_relation, mock_model_with_columns
+    ):
+        context["config"] = Mock()
+        context["config"].get = Mock(return_value="parquet")
+
+        context["log"] = Mock()
+        context["run_query_as"] = Mock()
+
+        self.run_macro_raw(
+            template_bundle.template,
+            "databricks__alter_column_comment",
+            mock_relation,
+            mock_model_with_columns.columns,
+        )
+
+        context["run_query_as"].assert_not_called()
+        context["log"].assert_called_once_with(
+            "WARNING - requested to update column comments, "
+            "but file format parquet does not support that."
+        )
+
+    def test_databricks__persist_docs_relation_only(
+        self, template_bundle, context, mock_relation, mock_model_with_description
+    ):
+        context["config"] = MagicMock()
+        context["config"].persist_relation_docs.return_value = True
+
+        context["run_query_as"] = Mock()
+
+        self.run_macro_raw(
+            template_bundle.template,
+            "databricks__persist_docs",
+            mock_relation,
+            mock_model_with_description,
+            True,  # for_relation
+            False,  # for_columns
+        )
+
+        sql = context["run_query_as"].call_args[0][0]
+        expected_sql = (
+            "COMMENT ON TABLE `test_db`.`test_schema`.`test_table` IS 'This is a test model'"
+        )
+        assert self.clean_sql(sql) == self.clean_sql(expected_sql)