class_docstr: Checks to see if a join between two semantic models should be allowed.
class_docstr_tok: ["Checks","to","see","if","a","join","between","two","semantic","models","should","be","allowed","."]
docstr: Get valid join type used to join semantic models on given entity, if exists.
docstr_tok: ["Get","valid","join","type","used","to","join","semantic","models","on","given","entity",",","if","exists","."]
code: def get_valid_semantic_model_entity_join_type(
      self,
      left_semantic_model_reference: SemanticModelReference,
      right_semantic_model_reference: SemanticModelReference,
      on_entity_reference: EntityReference,
  ) -> Optional[SemanticModelEntityJoinType]:
      """Get valid join type used to join semantic models on given entity, if exists."""
      left_entity = (
          self._semantic_model_lookup.get_entity_in_semantic_model(
              SemanticModelElementReference.create_from_references(
                  left_semantic_model_reference, on_entity_reference
              )
          )
      )
  
      right_entity = (
          self._semantic_model_lookup.get_entity_in_semantic_model(
              SemanticModelElementReference.create_from_references(
                  right_semantic_model_reference, on_entity_reference
              )
          )
      )
      if left_entity is None or right_entity is None:
          return None
  
      left_semantic_model = (
          self._semantic_model_lookup.get_by_reference(
              left_semantic_model_reference
          )
      )
      right_semantic_model = (
          self._semantic_model_lookup.get_by_reference(
              right_semantic_model_reference
          )
      )
      assert (
          left_semantic_model
      ), "Type refinement. If you see this error something has refactored wrongly"
      assert (
          right_semantic_model
      ), "Type refinement. If you see this error something has refactored wrongly"
  
      if (
          left_semantic_model.has_validity_dimensions
          and right_semantic_model.has_validity_dimensions
      ):
          # We cannot join two semantic models with validity dimensions due to concerns with unexpected fanout
          # due to the key structure of these semantic models. Applying multi-stage validity window filters can
          # also lead to unexpected removal of interim join keys. Note this will need to be updated if we enable
          # measures in such semantic models, since those will need to be converted to a different type of semantic model
          # to support measure computation.
          return None
  
      if right_entity.type is EntityType.NATURAL:
          if not right_semantic_model.has_validity_dimensions:
              # There is no way to refine this to a single row per key, so we cannot support this join
              return None
  
      join_type = SemanticModelEntityJoinType(
          left_entity.type, right_entity.type
      )
  
      if join_type in SemanticModelJoinEvaluator._VALID_ENTITY_JOINS:
          return join_type
      elif (
          join_type in SemanticModelJoinEvaluator._INVALID_ENTITY_JOINS
      ):
          return None
  
      raise RuntimeError(f"Join type not handled: {join_type}")
  
file_path: metricflow/metricflow/model/semantics/semantic_model_join_evaluator.py
imports: from __future__ import annotations
  from dataclasses import dataclass
  from typing import Dict, List, Optional
  from dbt_semantic_interfaces.pretty_print import pformat_big_objects
  from dbt_semantic_interfaces.protocols.entity import EntityType
  from dbt_semantic_interfaces.references import EntityReference, SemanticModelElementReference, SemanticModelReference
  from metricflow.instances import EntityInstance, InstanceSet
  from metricflow.protocols.semantics import SemanticModelAccessor
label_desc: Use image node_id 4 for calling the SemanticModelJoinEvaluator obj's underlying member method code with example usage: obj.get_valid_semantic_model_entity_join_type(left_semantic_model_reference, right_semantic_model_reference, on_entity_reference) and returns: None, None, join_type, None, None