Repository: dbt-labs/dbt-core

Issue:
[CT-729] [Bug] unrendered_config in manifest.json doesn't update correctly from model properties yaml
### Is there an existing issue for this?

- [X] I have searched the existing issues

### Current Behavior

Config changes from model properties yaml are not correctly propagated to the manifest.json, thus not showing up as a state change when using the `state:modified` selector.

### Expected Behavior

I expect the config changes from the model properties yaml to be correctly propagated to the `manifest.json` - "unrendered_config", just like it does from the config changes made in `dbt_project.yml`.

This will fix the state:modified selector to correctly detect my config changes made in the model properties yaml files.

### Steps To Reproduce

1. Clone [the jaffle shop example](https://github.com/dbt-labs/jaffle_shop ), and set up the profiles.yml to get dbt working.
2. Run `dbt compile`. Look for `customers` model in `target/manifest.json` - has `"unrendered_config": {"materialized": "table"}`
3. Copy `target/manifest.json` to top directory. 
4. Go to `models/schemas.yaml` and add the config block for customers model.
```
- name: customers
   config:
     materialized: view
```
5.  Run `dbt compile`. Look for `customers` model in `target/manifest.json` - still has `"unrendered_config": {"materialized": "table"}`. **The materialization config change hasn't been propagated**
5-1. Side-effect (which is the real problem for me): Run `dbt ls -s state:modified --state .` 
```
The selection criterion 'state:modified' does not match any nodes
No nodes selected!
```
6. Go to `dbt_project.yml`, and update the model config as below:
```
models:
  jaffle_shop:
      materialized: table
      customers:
        materialized: view
      staging:
        materialized: view
```
7. Run `dbt compile`. Look for `customers` model in `target/manifest.json` - now the updated config is shown here: `"unrendered_config": {"materialized": "table"}`.
7-1. Run `dbt ls -s state:modified --state .` 
```
jaffle_shop.customers
jaffle_shop.not_null_customers_customer_id
jaffle_shop.relationships_orders_customer_id__customer_id__ref_customers_
jaffle_shop.unique_customers_customer_id
```
I expect the same result from step 5-1.

### Relevant log output

_No response_

### Environment

```markdown
- OS: MacOS 12.1
- Python: 3.8.9
- dbt: 1.1.0 (dbt-bigquery 1.1.0)
```


### What database are you using dbt with?

bigquery

### Additional Context

Similar issue is reported for the jinja config macro:
https://github.com/dbt-labs/dbt-core/issues/3680
But the fix for the jinja config macro won't necessarily fix this issue.


Discussion:
Agree that https://github.com/dbt-labs/dbt-core/issues/3576 and https://github.com/dbt-labs/dbt-core/issues/3680 are related to the larger topic here, but actually separate from the specific bug reported here.

The bug here seems much easier to reproduce, and (hopefully) to get to the bottom of why configurations defined in standard `.yml` files aren't being reflected in `unrendered_config`.

Ideally, `unrendered_config` would include (as the name says) the unrendered versions of configs in `.yml` files, such that if your config looks like:
```
- name: customers
   config:
     materialized: "{{ 'view' if target.name == 'dev' else 'table' }}"
```
We'd store that whole Jinja expression, rather than `'view'` or `'table'` (depending on the environment), leading to cross-env "false positives" for `state:modified`.

As a practical matter, even just storing `'view'` or `'table'` sounds better than the status quo, where the materialization change fails to propagate at all, leading to a "false negative" worse.

Resolving patch:
diff --git a/core/dbt/parser/base.py b/core/dbt/parser/base.py
--- a/core/dbt/parser/base.py
+++ b/core/dbt/parser/base.py
@@ -309,7 +309,9 @@ def update_parsed_node_config(
 
         # unrendered_config is used to compare the original database/schema/alias
         # values and to handle 'same_config' and 'same_contents' calls
-        parsed_node.unrendered_config = config.build_config_dict(rendered=False)
+        parsed_node.unrendered_config = config.build_config_dict(
+            rendered=False, patch_config_dict=patch_config_dict
+        )
 
         parsed_node.config_call_dict = config._config_call_dict
 


Test patch:
diff --git a/tests/functional/artifacts/expected_manifest.py b/tests/functional/artifacts/expected_manifest.py
--- a/tests/functional/artifacts/expected_manifest.py
+++ b/tests/functional/artifacts/expected_manifest.py
@@ -205,9 +205,13 @@ def expected_seeded_manifest(project, model_database=None, quote_model=False):
         schema="test", docs={"node_color": None, "show": False}
     )
 
-    unrendered_model_config = get_unrendered_model_config(materialized="view")
+    unrendered_model_config = get_unrendered_model_config(
+        materialized="view", docs={"show": False}
+    )
 
-    unrendered_second_config = get_unrendered_model_config(schema="test", materialized="view")
+    unrendered_second_config = get_unrendered_model_config(
+        schema="test", materialized="view", docs={"show": False}
+    )
 
     seed_config = get_rendered_seed_config()
     unrendered_seed_config = get_unrendered_seed_config()
diff --git a/tests/functional/configs/test_configs_in_schema_files.py b/tests/functional/configs/test_configs_in_schema_files.py
--- a/tests/functional/configs/test_configs_in_schema_files.py
+++ b/tests/functional/configs/test_configs_in_schema_files.py
@@ -23,7 +23,7 @@
         meta:
             owner: 'Julie Smith'
             my_attr: "{{ var('my_var') }}"
-        materialization: view
+        materialized: view
 
     columns:
       - name: id
@@ -63,6 +63,22 @@
 select 4 as id, 2 as value
 """
 
+models_no_materialized__model_sql = """
+{{
+    config(
+        tags=['tag_1_in_model'],
+    )
+}}
+
+{{
+    config(
+        tags=['tag_2_in_model'],
+    )
+}}
+
+select 4 as id, 2 as value
+"""
+
 seeds_alt__some_seed_csv = """id,value
 4,2
 """
@@ -190,6 +206,27 @@ def test_config_layering(
         assert tables["model"] == "table"
         check_relations_equal(project.adapter, ["some_seed", "model"])
 
+        # Remove materialized config from model
+        write_file(
+            models_no_materialized__model_sql,
+            project.project_root,
+            "models",
+            "tagged",
+            "model.sql",
+        )
+        results = run_dbt(["run"])
+        assert len(results) == 2
+        manifest = get_manifest(project.project_root)
+        model_node = manifest.nodes[model_id]
+
+        assert model_node.config.materialized == "view"
+        model_unrendered_config = {
+            "materialized": "view",
+            "meta": {"my_attr": "TESTING", "owner": "Julie Smith"},
+            "tags": ["tag_1_in_model", "tag_2_in_model"],
+        }
+        assert model_node.unrendered_config == model_unrendered_config
+
         # look for test meta
         schema_file_id = model_node.patch_path
         schema_file = manifest.files[schema_file_id]