diff --git a/.changes/unreleased/Fixes-20231024-110151.yaml b/.changes/unreleased/Fixes-20231024-110151.yaml new file mode 100644 index 00000000000..711f431be8a --- /dev/null +++ b/.changes/unreleased/Fixes-20231024-110151.yaml @@ -0,0 +1,6 @@ +kind: Fixes +body: Handle unknown `type_code` for model contracts +time: 2023-10-24T11:01:51.980781-06:00 +custom: + Author: dbeatty10 + Issue: 8877 8353 diff --git a/plugins/postgres/dbt/adapters/postgres/connections.py b/plugins/postgres/dbt/adapters/postgres/connections.py index ac7df536bdb..50c609f54bb 100644 --- a/plugins/postgres/dbt/adapters/postgres/connections.py +++ b/plugins/postgres/dbt/adapters/postgres/connections.py @@ -204,4 +204,7 @@ def get_response(cls, cursor) -> AdapterResponse: @classmethod def data_type_code_to_name(cls, type_code: int) -> str: - return string_types[type_code].name + if type_code in string_types: + return string_types[type_code].name + else: + return f"unknown type_code {type_code}" diff --git a/tests/functional/contracts/test_nonstandard_data_type.py b/tests/functional/contracts/test_nonstandard_data_type.py new file mode 100644 index 00000000000..4ee559ff4e5 --- /dev/null +++ b/tests/functional/contracts/test_nonstandard_data_type.py @@ -0,0 +1,76 @@ +import pytest +from dbt.tests.util import run_dbt, run_dbt_and_capture + + +my_numeric_model_sql = """ +select + 12.34 as price +""" + +my_money_model_sql = """ +select + cast('12.34' as money) as price +""" + +model_schema_money_yml = """ +models: + - name: my_model + config: + contract: + enforced: true + columns: + - name: price + data_type: money +""" + +model_schema_numeric_yml = """ +models: + - name: my_model + config: + contract: + enforced: true + columns: + - name: price + data_type: numeric +""" + + +class TestModelContractUnrecognizedTypeCode1: + @pytest.fixture(scope="class") + def models(self): + return { + "my_model.sql": my_money_model_sql, + "schema.yml": model_schema_money_yml, + } + + def test_nonstandard_data_type(self, project): + run_dbt(["run"], expect_pass=True) + + +class TestModelContractUnrecognizedTypeCodeActualMismatch: + @pytest.fixture(scope="class") + def models(self): + return { + "my_model.sql": my_money_model_sql, + "schema.yml": model_schema_numeric_yml, + } + + def test_nonstandard_data_type(self, project): + expected_msg = "unknown type_code 790 | DECIMAL | data type mismatch" + _, logs = run_dbt_and_capture(["run"], expect_pass=False) + assert expected_msg in logs + + +class TestModelContractUnrecognizedTypeCodeExpectedMismatch: + @pytest.fixture(scope="class") + def models(self): + return { + "my_model.sql": my_numeric_model_sql, + "schema.yml": model_schema_money_yml, + } + + def test_nonstandard_data_type(self, project): + expected_msg = "DECIMAL | unknown type_code 790 | data type mismatch" + _, logs = run_dbt_and_capture(["run"], expect_pass=False) + print(logs) + assert expected_msg in logs