From 99c9d2a52fe6d8220e35caf5b0113855be990f1f Mon Sep 17 00:00:00 2001 From: Mike Alfare <13974384+mikealfare@users.noreply.github.com> Date: Tue, 31 Oct 2023 23:31:37 -0400 Subject: [PATCH] ADAP-973: Fix issue where materialized views were being mapped as views in catalog queries (#653) * changelog * write test demonstrating the issue * update the catalog query to identify materialized views * explicitly state that materialized views have a relkind of v --- .../unreleased/Fixes-20231030-234315.yaml | 6 +++ dbt/include/redshift/macros/catalog.sql | 20 ++++++++- .../functional/adapter/catalog_tests/files.py | 33 ++++++++++++++ .../catalog_tests/test_relation_types.py | 44 +++++++++++++++++++ 4 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 .changes/unreleased/Fixes-20231030-234315.yaml create mode 100644 tests/functional/adapter/catalog_tests/files.py create mode 100644 tests/functional/adapter/catalog_tests/test_relation_types.py diff --git a/.changes/unreleased/Fixes-20231030-234315.yaml b/.changes/unreleased/Fixes-20231030-234315.yaml new file mode 100644 index 000000000..823e252dd --- /dev/null +++ b/.changes/unreleased/Fixes-20231030-234315.yaml @@ -0,0 +1,6 @@ +kind: Fixes +body: Catalog queries assign the appropriate type for materialized views +time: 2023-10-30T23:43:15.281772-04:00 +custom: + Author: mikealfare + Issue: "652" diff --git a/dbt/include/redshift/macros/catalog.sql b/dbt/include/redshift/macros/catalog.sql index b34460035..69dc71713 100644 --- a/dbt/include/redshift/macros/catalog.sql +++ b/dbt/include/redshift/macros/catalog.sql @@ -23,13 +23,28 @@ order by "column_index" ), + materialized_views as ( + select + table_schema as nspname, + table_name as relname + from information_schema.views + where ( + {%- for schema in schemas -%} + upper(table_schema) = upper('{{ schema }}'){%- if not loop.last %} or {% endif -%} + {%- endfor -%} + ) + and table_catalog = '{{ database }}' + and view_definition ilike '%create materialized view%' + ), + early_binding as ( select '{{ database }}'::varchar as table_database, sch.nspname as table_schema, tbl.relname as table_name, - case tbl.relkind - when 'v' then 'VIEW' + case + when tbl.relkind = 'v' and materialized_views.relname is not null then 'MATERIALIZED VIEW' + when tbl.relkind = 'v' then 'VIEW' else 'BASE TABLE' end as table_type, tbl_desc.description as table_comment, @@ -43,6 +58,7 @@ join pg_catalog.pg_attribute col on col.attrelid = tbl.oid left outer join pg_catalog.pg_description tbl_desc on (tbl_desc.objoid = tbl.oid and tbl_desc.objsubid = 0) left outer join pg_catalog.pg_description col_desc on (col_desc.objoid = tbl.oid and col_desc.objsubid = col.attnum) + left outer join materialized_views on (materialized_views.nspname = sch.nspname and materialized_views.relname = tbl.relname) where ( {%- for schema in schemas -%} upper(sch.nspname) = upper('{{ schema }}'){%- if not loop.last %} or {% endif -%} diff --git a/tests/functional/adapter/catalog_tests/files.py b/tests/functional/adapter/catalog_tests/files.py new file mode 100644 index 000000000..9c19522e7 --- /dev/null +++ b/tests/functional/adapter/catalog_tests/files.py @@ -0,0 +1,33 @@ +MY_SEED = """ +id,value,record_valid_date +1,100,2023-01-01 00:00:00 +2,200,2023-01-02 00:00:00 +3,300,2023-01-02 00:00:00 +""".strip() + + +MY_TABLE = """ +{{ config( + materialized='table', +) }} +select * +from {{ ref('my_seed') }} +""" + + +MY_VIEW = """ +{{ config( + materialized='view', +) }} +select * +from {{ ref('my_seed') }} +""" + + +MY_MATERIALIZED_VIEW = """ +{{ config( + materialized='materialized_view', +) }} +select * +from {{ ref('my_seed') }} +""" diff --git a/tests/functional/adapter/catalog_tests/test_relation_types.py b/tests/functional/adapter/catalog_tests/test_relation_types.py new file mode 100644 index 000000000..9b9156dec --- /dev/null +++ b/tests/functional/adapter/catalog_tests/test_relation_types.py @@ -0,0 +1,44 @@ +from dbt.contracts.results import CatalogArtifact +from dbt.tests.util import run_dbt +import pytest + +from tests.functional.adapter.catalog_tests import files + + +class TestCatalogRelationTypes: + @pytest.fixture(scope="class", autouse=True) + def seeds(self): + return {"my_seed.csv": files.MY_SEED} + + @pytest.fixture(scope="class", autouse=True) + def models(self): + yield { + "my_table.sql": files.MY_TABLE, + "my_view.sql": files.MY_VIEW, + "my_materialized_view.sql": files.MY_MATERIALIZED_VIEW, + } + + @pytest.fixture(scope="class", autouse=True) + def docs(self, project): + run_dbt(["seed"]) + run_dbt(["run"]) + yield run_dbt(["docs", "generate"]) + + @pytest.mark.parametrize( + "node_name,relation_type", + [ + ("seed.test.my_seed", "BASE TABLE"), + ("model.test.my_table", "BASE TABLE"), + ("model.test.my_view", "VIEW"), + ("model.test.my_materialized_view", "MATERIALIZED VIEW"), + ], + ) + def test_relation_types_populate_correctly( + self, docs: CatalogArtifact, node_name: str, relation_type: str + ): + """ + This test addresses: https://github.com/dbt-labs/dbt-redshift/issues/652 + """ + assert node_name in docs.nodes + node = docs.nodes[node_name] + assert node.metadata.type == relation_type