Repository: dbt-labs/dbt-core

Issue:
[Bug] Using filter list with Jinja on metrics and metric input measures causes error when running `dbt parse`
### Is this a new bug in dbt-core?

- [X] I believe this is a new bug in dbt-core
- [X] I have searched the existing issues, and I could not find an existing issue for this bug

### Current Behavior

When you define a metric or metric input measure with a filter list and include Jinja in the list, `dbt parse` triggers an error. Example YAML:
```
metrics:
  - name: new_customer
    description: Unique count of new customers.
    label: New Customers
    type: simple
    type_params:
      measure: customers_with_orders
    filter:
      - "{{ Dimension('customer__customer_type') }}  = 'new'"
```
Running `dbt parse` in a repo with that metric definition triggers this error:
```
Compilation Error
  Could not render {{ Dimension('customer__customer_type') }}  = 'new': 'Dimension' is undefined
```
Meanwhile, if you apply the same filter as a string (example below), no error will be triggered.
```
metrics:
  - name: new_customer
    description: Unique count of new customers.
    label: New Customers
    type: simple
    type_params:
      measure: customers_with_orders
    filter: "{{ Dimension('customer__customer_type') }}  = 'new'"
```

### Expected Behavior

Applying the filter in a list should have the same impact as applying it as a string. Currently this limitation will prevent users from using multiple filters on metrics and metric input measures.

### Steps To Reproduce

1. Add a list-type filter on a metric or a metric input measure in a dbt project
2. Run `dbt parse` in the repo

### Relevant log output

```shell
Output when running dbt parse:

21:05:56  Running with dbt=1.7.3
21:05:56  Registered adapter: duckdb=1.7.0
21:05:56  Encountered an error:
Compilation Error
  Could not render {{ Dimension('customer__customer_type') }}  = 'new': 'Dimension' is undefined
```


### Environment

```markdown
- OS: Mac OSX 13.4.1
- Python: 3.9.16
- dbt: 1.7.3
```


### Which database adapter are you using with dbt?

other (mention it in "Additional Context")

### Additional Context

DuckDB


Discussion:

Resolving patch:
diff --git a/core/dbt/parser/schema_renderer.py b/core/dbt/parser/schema_renderer.py
--- a/core/dbt/parser/schema_renderer.py
+++ b/core/dbt/parser/schema_renderer.py
@@ -74,12 +74,13 @@ def should_render_keypath(self, keypath: Keypath) -> bool:
             elif self._is_norender_key(keypath[0:]):
                 return False
         elif self.key == "metrics":
-            # This ensures all key paths that end in 'filter' for a metric are skipped
-            if keypath[-1] == "filter":
+            # This ensures that metric filters are skipped
+            if keypath[-1] == "filter" or len(keypath) > 1 and keypath[-2] == "filter":
                 return False
             elif self._is_norender_key(keypath[0:]):
                 return False
         elif self.key == "saved_queries":
+            # This ensures that saved query filters are skipped
             if keypath[0] == "query_params" and len(keypath) > 1 and keypath[1] == "where":
                 return False
             elif self._is_norender_key(keypath[0:]):


Test patch:
diff --git a/tests/functional/metrics/fixtures.py b/tests/functional/metrics/fixtures.py
--- a/tests/functional/metrics/fixtures.py
+++ b/tests/functional/metrics/fixtures.py
@@ -763,6 +763,16 @@
         name: "years_tenure"
         filter: "{{ Dimension('id__loves_dbt') }} is true"
 
+  - name: collective_tenure_measure_filter_list
+    label: "Collective tenure2"
+    description: Total number of years of team experience
+    type: simple
+    type_params:
+      measure:
+        name: "years_tenure"
+        filter:
+          - "{{ Dimension('id__loves_dbt') }} is true"
+
   - name: collective_tenure_metric_filter_str
     label: Collective tenure3
     description: Total number of years of team experience
@@ -772,6 +782,15 @@
         name: "years_tenure"
     filter: "{{ Dimension('id__loves_dbt') }} is true"
 
+  - name: collective_tenure_metric_filter_list
+    label: Collective tenure4
+    description: Total number of years of team experience
+    type: simple
+    type_params:
+      measure:
+        name: "years_tenure"
+    filter:
+      - "{{ Dimension('id__loves_dbt') }} is true"
 
   - name: average_tenure_filter_str
     label: Average tenure of people who love dbt1
@@ -782,6 +801,17 @@
       metrics:
         - name: average_tenure
           filter: "{{ Dimension('id__loves_dbt') }} is true"
+
+  - name: average_tenure_filter_list
+    label: Average tenure of people who love dbt2
+    description: Average tenure of people who love dbt
+    type: derived
+    type_params:
+      expr: "average_tenure"
+      metrics:
+        - name: average_tenure
+          filter:
+            - "{{ Dimension('id__loves_dbt') }} is true"
 """
 
 duplicate_measure_metric_yml = """
diff --git a/tests/functional/metrics/test_metrics.py b/tests/functional/metrics/test_metrics.py
--- a/tests/functional/metrics/test_metrics.py
+++ b/tests/functional/metrics/test_metrics.py
@@ -415,8 +415,8 @@ def models(self):
             "people.sql": models_people_sql,
         }
 
-    # Tests that filters are parsed to their appropriate type
-    def test_string_filter_parsing(
+    # Tests that filters are parsed to their appropriate types
+    def test_filter_parsing(
         self,
         project,
     ):
@@ -436,22 +436,41 @@ def test_string_filter_parsing(
         )
         assert len(filters1) == 1
         assert filters1[0].where_sql_template == "{{ Dimension('id__loves_dbt') }} is true"
+        filters2 = (
+            manifest.metrics["metric.test.collective_tenure_measure_filter_list"]
+            .input_measures[0]
+            .filter.where_filters
+        )
+        assert len(filters2) == 1
+        assert filters2[0].where_sql_template == "{{ Dimension('id__loves_dbt') }} is true"
 
         # Test metrics with metric-level filters.
-        filters2 = manifest.metrics[
+        filters3 = manifest.metrics[
             "metric.test.collective_tenure_metric_filter_str"
         ].filter.where_filters
-        assert len(filters2) == 1
-        assert filters2[0].where_sql_template == "{{ Dimension('id__loves_dbt') }} is true"
+        assert len(filters3) == 1
+        assert filters3[0].where_sql_template == "{{ Dimension('id__loves_dbt') }} is true"
+        filters4 = manifest.metrics[
+            "metric.test.collective_tenure_metric_filter_list"
+        ].filter.where_filters
+        assert len(filters4) == 1
+        assert filters4[0].where_sql_template == "{{ Dimension('id__loves_dbt') }} is true"
 
         # Test derived metrics with input metric filters.
-        filters3 = (
+        filters5 = (
             manifest.metrics["metric.test.average_tenure_filter_str"]
             .input_metrics[0]
             .filter.where_filters
         )
-        assert len(filters3) == 1
-        assert filters3[0].where_sql_template == "{{ Dimension('id__loves_dbt') }} is true"
+        assert len(filters5) == 1
+        assert filters5[0].where_sql_template == "{{ Dimension('id__loves_dbt') }} is true"
+        filters6 = (
+            manifest.metrics["metric.test.average_tenure_filter_list"]
+            .input_metrics[0]
+            .filter.where_filters
+        )
+        assert len(filters6) == 1
+        assert filters6[0].where_sql_template == "{{ Dimension('id__loves_dbt') }} is true"
 
 
 class TestDuplicateInputMeasures: