diff --git a/dbt/include/snowflake/macros/adapters.sql b/dbt/include/snowflake/macros/adapters.sql index e780b9765..66274d51c 100644 --- a/dbt/include/snowflake/macros/adapters.sql +++ b/dbt/include/snowflake/macros/adapters.sql @@ -134,10 +134,16 @@ {% endmacro %} -{% macro snowflake__list_relations_without_caching(schema_relation, max_iter=10, max_results_per_iter=10000) %} +{% macro snowflake__list_relations_without_caching(schema_relation, max_iter=10, max_results_per_iter=10000, query_pre_hook=None) %} + {# -- Use query_pre_hook for optional configurations prior to fetching relations. For sake of + -- consistent use, place ;s in the query_pre_hook definition, not this macro. #} {%- set max_total_results = max_results_per_iter * max_iter -%} {%- set sql -%} + {% if query_pre_hook %} + {{ query_pre_hook }} + {% endif -%} + {% if schema_relation is string %} show objects in {{ schema_relation }} limit {{ max_results_per_iter }}; {% else %} diff --git a/tests/functional/adapter/list_relations_tests/test_show_objects.py b/tests/functional/adapter/list_relations_tests/test_show_objects.py index e5eee39d9..822f9cafa 100644 --- a/tests/functional/adapter/list_relations_tests/test_show_objects.py +++ b/tests/functional/adapter/list_relations_tests/test_show_objects.py @@ -3,10 +3,12 @@ import pytest +from pathlib import Path + from dbt.adapters.factory import get_adapter_by_type from dbt.adapters.snowflake import SnowflakeRelation -from dbt.tests.util import run_dbt, get_connection +from dbt.tests.util import run_dbt, get_connection, write_file SEED = """ @@ -41,8 +43,40 @@ """ ) +_MODEL_ICEBERG = """ +{{ + config( + materialized = "table", + table_format="iceberg", + external_volume="s3_iceberg_snow", + ) +}} + +select 1 +""" + +macro_template_for_iceberg_quoted_identifiers_flag_test = """ +{{% macro list_relations_without_caching(schema_relation={}) -%}} + {{%- set pre_hook = 'ALTER SESSION SET QUOTED_IDENTIFIERS_IGNORE_CASE = true;' -%}} + {{%- set result = snowflake__list_relations_without_caching(schema_relation=schema_relation, query_pre_hook=pre_hook) -%}} + {{%- do return(result) -%}} +{{% endmacro %}} +""" + -class TestShowObjects: +class ShowObjectsBase: + @staticmethod + def list_relations_without_caching(project) -> List[SnowflakeRelation]: + my_adapter = get_adapter_by_type("snowflake") + schema = my_adapter.Relation.create( + database=project.database, schema=project.test_schema, identifier="" + ) + with get_connection(my_adapter): + relations = my_adapter.list_relations_without_caching(schema) + return relations + + +class TestShowObjects(ShowObjectsBase): views: int = 10 tables: int = 10 dynamic_tables: int = 10 @@ -66,16 +100,6 @@ def setup(self, project): run_dbt(["seed"]) run_dbt(["run"]) - @staticmethod - def list_relations_without_caching(project) -> List[SnowflakeRelation]: - my_adapter = get_adapter_by_type("snowflake") - schema = my_adapter.Relation.create( - database=project.database, schema=project.test_schema, identifier="" - ) - with get_connection(my_adapter): - relations = my_adapter.list_relations_without_caching(schema) - return relations - def test_list_relations_without_caching(self, project): relations = self.list_relations_without_caching(project) assert len([relation for relation in relations if relation.is_view]) == self.views @@ -87,3 +111,27 @@ def test_list_relations_without_caching(self, project): len([relation for relation in relations if relation.is_dynamic_table]) == self.dynamic_tables ) + + +class TestShowIcebergObjects(ShowObjectsBase): + @pytest.fixture(scope="class") + def project_config_update(self): + return {"flags": {"enable_iceberg_materializations": True}} + + @pytest.fixture(scope="class") + def models(self): + return {"my_model.sql": _MODEL_ICEBERG} + + def test_quoting_ignore_flag_doesnt_break_iceberg_metadata(self, project): + """We inject the QUOTED_IDENTIFIERS_IGNORE_CASE into the underlying query that fetches + objects which will fail without proper normalization within the python function after + the list relations macro returns.""" + macro_file = project.project_root / Path("macros") / Path("macros_for_this_test.sql") + write_file( + macro_template_for_iceberg_quoted_identifiers_flag_test.format(project.test_schema), + macro_file, + ) + + run_dbt(["run"]) + + self.list_relations_without_caching(project) diff --git a/tests/functional/iceberg/test_table_basic.py b/tests/functional/iceberg/test_table_basic.py index b7af60852..e835a5fce 100644 --- a/tests/functional/iceberg/test_table_basic.py +++ b/tests/functional/iceberg/test_table_basic.py @@ -35,11 +35,6 @@ def test_iceberg_tables_build_and_can_be_referred(self, project): run_results = run_dbt() assert len(run_results) == 5 - def test_iceberg_tables_handle_quoting_ignore_flag(self, project): - project.run_sql("ALTER SESSION SET QUOTED_IDENTIFIERS_IGNORE_CASE = true;") - run_results = run_dbt() - assert len(run_results) == 5 - class TestIcebergTableTypeBuildsOnExistingTable: @pytest.fixture(scope="class")