Repository: dbt-labs/dbt-core
Pull request: [CT-2888] Support dbt-semantic-interfaces 0.2.0
resolves #8247 

### Problem

There is a bug currently in core main and 1.6.latest where-in daemonic invocations of core get killed off due to a multi processing in DSI 0.1.0rc1. This is fixed in DSI 0.2.0 Additionally there are breaking changes in DSI 0.2.0 that we need to in core (and backported to core 1.6). This PR updates us to DSI 0.2.0 and includes the necessary changes to support it.
### Solution

### Checklist

- [X] I have read [the contributing guide](https://github.com/dbt-labs/dbt-core/blob/main/CONTRIBUTING.md) and understand what's expected of me  
- [X] I have run this code in development and it appears to resolve the stated issue  
- [X] This PR includes tests, or tests are not required/relevant for this PR
- [X] This PR has no interface changes (e.g. macros, cli, logs, json artifacts, config files, adapter interface, etc) or this PR has already received feedback and approval from Product or DX


Problem statement:
[CT-2888] Support DSI 0.2.0
DSI 0.2.0 is dropping soon. It has a fix for an a runtime exception being encountered when dbt-core is run in a daemonic environment. There are additionally some breaking protocol changes that come with it that we'll need to support. This work will need to get backported to 1.6.latest

Hints from issue discussion:

Commit message: Fix metric filter specifications in existing tests

Patch to review:
diff --git a/core/dbt/contracts/graph/nodes.py b/core/dbt/contracts/graph/nodes.py
index 3e191e90855..59ac576db79 100644
--- a/core/dbt/contracts/graph/nodes.py
+++ b/core/dbt/contracts/graph/nodes.py
@@ -50,6 +50,7 @@
 from dbt.node_types import ModelLanguage, NodeType, AccessType
 from dbt_semantic_interfaces.call_parameter_sets import FilterCallParameterSets
 from dbt_semantic_interfaces.references import (
+    EntityReference,
     MeasureReference,
     LinkableElementReference,
     SemanticModelReference,
@@ -1498,6 +1499,7 @@ class SemanticModel(GraphNode):
     refs: List[RefArgs] = field(default_factory=list)
     created_at: float = field(default_factory=lambda: time.time())
     config: SemanticModelConfig = field(default_factory=SemanticModelConfig)
+    primary_entity: Optional[str] = None
 
     @property
     def entity_references(self) -> List[LinkableElementReference]:
@@ -1580,6 +1582,14 @@ def checked_agg_time_dimension_for_measure(
         )
         return TimeDimensionReference(element_name=agg_time_dimension_name)
 
+    @property
+    def primary_entity_reference(self) -> Optional[EntityReference]:
+        return (
+            EntityReference(element_name=self.primary_entity)
+            if self.primary_entity is not None
+            else None
+        )
+
 
 # ====================================
 # Patches
diff --git a/core/dbt/contracts/graph/unparsed.py b/core/dbt/contracts/graph/unparsed.py
index babbca64a21..585ac9cc3e0 100644
--- a/core/dbt/contracts/graph/unparsed.py
+++ b/core/dbt/contracts/graph/unparsed.py
@@ -728,6 +728,7 @@ class UnparsedSemanticModel(dbtClassMixin):
     entities: List[UnparsedEntity] = field(default_factory=list)
     measures: List[UnparsedMeasure] = field(default_factory=list)
     dimensions: List[UnparsedDimension] = field(default_factory=list)
+    primary_entity: Optional[str] = None
 
 
 def normalize_date(d: Optional[datetime.date]) -> Optional[datetime.datetime]:
diff --git a/core/dbt/parser/schema_yaml_readers.py b/core/dbt/parser/schema_yaml_readers.py
index 8f7b1519fb6..2f2a3eb18e6 100644
--- a/core/dbt/parser/schema_yaml_readers.py
+++ b/core/dbt/parser/schema_yaml_readers.py
@@ -532,6 +532,7 @@ def parse_semantic_model(self, unparsed: UnparsedSemanticModel):
             measures=self._get_measures(unparsed.measures),
             dimensions=self._get_dimensions(unparsed.dimensions),
             defaults=unparsed.defaults,
+            primary_entity=unparsed.primary_entity,
         )
 
         ctx = generate_parse_semantic_models(
diff --git a/core/setup.py b/core/setup.py
index a0ccdc45e58..7c9f500b50a 100644
--- a/core/setup.py
+++ b/core/setup.py
@@ -76,8 +76,7 @@
         "hologram~=0.0.16",  # includes transitive dependencies on python-dateutil and jsonschema
         "minimal-snowplow-tracker~=0.0.2",
         # DSI is under active development, so we're pinning to specific dev versions for now.
-        # TODO: Before RC/final release, update to use ~= pinning.
-        "dbt-semantic-interfaces~=0.1.0rc1",
+        "dbt-semantic-interfaces~=0.2.0",
         # ----
         # Expect compatibility with all new versions of these packages, so lower bounds only.
         "packaging>20.9",
diff --git a/tests/functional/duplicates/test_duplicate_metric.py b/tests/functional/duplicates/test_duplicate_metric.py
index 3a9c3205796..a5f6b60e8f3 100644
--- a/tests/functional/duplicates/test_duplicate_metric.py
+++ b/tests/functional/duplicates/test_duplicate_metric.py
@@ -25,7 +25,7 @@
     type_params:
       measure:
         name: "years_tenure"
-        filter: "{{dimension('loves_dbt')}} is true"
+        filter: "{{ Dimension('people_entity__loves_dbt') }} is true"
 """
 
 
diff --git a/tests/functional/metrics/fixtures.py b/tests/functional/metrics/fixtures.py
index 87fc67c10c6..65d61ad74ad 100644
--- a/tests/functional/metrics/fixtures.py
+++ b/tests/functional/metrics/fixtures.py
@@ -70,7 +70,7 @@
     type_params:
       measure:
         name: "years_tenure"
-        filter: "{{dimension('loves_dbt')}} is true"
+        filter: "{{ Dimension('id__loves_dbt') }} is true"
 
   - name: average_tenure
     label: "Average tenure"
@@ -115,7 +115,7 @@
     type_params:
       measure:
         name: years_tenure
-        filter: "{{dimension('loves_dbt')}} is true"
+        filter: "{{ Dimension('id__loves_dbt') }} is true"
 
   - name: collective_window
     label: "Collective window"
@@ -124,7 +124,7 @@
     type_params:
       measure:
         name: years_tenure
-        filter: "{{dimension('loves_dbt')}} is true"
+        filter: "{{ Dimension('id__loves_dbt') }} is true"
       window: 14 days
 
   - name: average_tenure
@@ -452,7 +452,7 @@
     type_params:
       measure:
         name: years_tenure
-        filter: "{{dimension('loves_dbt')}} is true"
+        filter: "{{ Dimension('id__loves_dbt') }} is true"
 
 """
 
@@ -479,7 +479,7 @@
     type_params:
       measure:
         name: years_tenure
-        filter: "{{dimension('loves_dbt')}} is true"
+        filter: "{{ Dimension('id__loves_dbt') }} is true"
 
 """
 
diff --git a/tests/functional/partial_parsing/fixtures.py b/tests/functional/partial_parsing/fixtures.py
index 9da5a6f5025..52578d90308 100644
--- a/tests/functional/partial_parsing/fixtures.py
+++ b/tests/functional/partial_parsing/fixtures.py
@@ -353,7 +353,7 @@
     type_params:
       measure:
         name: customers
-        filter: "{{dimension('loves_dbt')}} is true"
+        filter: "{{ Dimension('id__loves_dbt') }} is true"
     +meta:
         is_okr: True
     tags:
@@ -472,7 +472,7 @@
     type_params:
       measure:
         name: years_tenure
-        filter: "{{dimension('loves_dbt')}} is true"
+        filter: "{{ Dimension('id__loves_dbt') }} is true"
 
 """
 
@@ -619,7 +619,7 @@
     type_params:
       measure:
         name: years_tenure
-        filter: "{{dimension('loves_dbt')}} is true"
+        filter: "{{ Dimension('id__loves_dbt') }} is true"
 
 """
 
@@ -1008,7 +1008,7 @@
     type_params:
       measure:
         name: years_tenure
-        filter: "{{dimension('loves_dbt')}} is true"
+        filter: "{{ Dimension('id__loves_dbt') }} is true"
 
 """
 
diff --git a/tests/functional/semantic_models/test_semantic_model_parsing.py b/tests/functional/semantic_models/test_semantic_model_parsing.py
index fbe21749772..6b0fe643691 100644
--- a/tests/functional/semantic_models/test_semantic_model_parsing.py
+++ b/tests/functional/semantic_models/test_semantic_model_parsing.py
@@ -61,6 +61,8 @@
       - name: user
         type: foreign
         expr: user_id
+      - name: id
+        type: primary
 
 metrics:
   - name: records_with_revenue
diff --git a/tests/unit/test_semantic_layer_nodes_satisfy_protocols.py b/tests/unit/test_semantic_layer_nodes_satisfy_protocols.py
index 4d7618b39b9..083924fb428 100644
--- a/tests/unit/test_semantic_layer_nodes_satisfy_protocols.py
+++ b/tests/unit/test_semantic_layer_nodes_satisfy_protocols.py
@@ -169,7 +169,7 @@ def test_metric_node_satisfies_protocol():
 
 def test_where_filter_satisfies_protocol():
     where_filter = WhereFilter(
-        where_sql_template="{{ dimension('dimension_name') }} AND {{ time_dimension('time_dimension_name', 'month') }} AND {{ entity('entity_name') }}"
+        where_sql_template="{{ Dimension('enity_name__dimension_name') }} AND {{ TimeDimension('entity_name__time_dimension_name', 'month') }} AND {{ Entity('entity_name') }}"
     )
     assert isinstance(where_filter, RuntimeCheckableWhereFilter)
 
diff --git a/tests/unit/test_yaml_renderer.py b/tests/unit/test_yaml_renderer.py
index 783cc69905e..9a703617aea 100644
--- a/tests/unit/test_yaml_renderer.py
+++ b/tests/unit/test_yaml_renderer.py
@@ -105,14 +105,14 @@ def test__metrics(self):
         dct = {
             "name": "test{{ metric_name_end }}",
             "description": "{{ docs('my_doc') }}",
-            "filter": "{{ dimension('my_dim') }} = false",
+            "filter": "{{ Dimension('my_entity__my_dim') }} = false",
         }
         # We expect the expression and description will not be rendered, but
         # other fields will be
         expected = {
             "name": "test_metric",
             "description": "{{ docs('my_doc') }}",
-            "filter": "{{ dimension('my_dim') }} = false",
+            "filter": "{{ Dimension('my_entity__my_dim') }} = false",
         }
         dct = renderer.render_data(dct)
         self.assertEqual(dct, expected)


Code review comments:
diff_hunk: @@ -0,0 +1,6 @@
+kind: Dependencies
+body: Support dbt-semantic-interfaces 0.2.0
+time: 2023-07-28T13:52:27.207241-07:00
+custom:
+  Author: QMalcolm
+  PR: "8247"
path: .changes/unreleased/Dependencies-20230728-135227.yaml
text: @user1:
This type and Security specifically point at PR instead of issue.
```suggestion
  PR: "8250"
```