class_docstr: Generates an SQL query plan from a node in the a metric dataflow plan.
class_docstr_tok: ["Generates","an","SQL","query","plan","from","a","node","in","the","a","metric","dataflow","plan","."]
docstr: Generate time range join SQL.
docstr_tok: ["Generate","time","range","join","SQL","."]
code: def visit_join_over_time_range_node(
      self, node: JoinOverTimeRangeNode
  ) -> SqlDataSet:
      """Generate time range join SQL."""
      table_alias_to_instance_set: OrderedDict[
          str, InstanceSet
      ] = OrderedDict()
  
      input_data_set = node.parent_node.accept(self)
      input_data_set_alias = self._next_unique_table_alias()
  
      metric_time_dimension_spec: Optional[TimeDimensionSpec] = None
      metric_time_dimension_instance: Optional[
          TimeDimensionInstance
      ] = None
      for instance in input_data_set.metric_time_dimension_instances:
          if len(instance.spec.entity_links) == 0:
              metric_time_dimension_instance = instance
              metric_time_dimension_spec = instance.spec
              break
  
      assert metric_time_dimension_spec
      time_spine_data_set_alias = self._next_unique_table_alias()
  
      metric_time_dimension_column_name = (
          self.column_association_resolver.resolve_spec(
              metric_time_dimension_spec
          ).column_name
      )
  
      # Assemble time_spine dataset with metric_time_dimension to join.
      # Granularity of time_spine column should match granularity of metric_time column from parent dataset.
      assert metric_time_dimension_instance
      time_spine_data_set = self._make_time_spine_data_set(
          metric_time_dimension_instance=metric_time_dimension_instance,
          metric_time_dimension_column_name=metric_time_dimension_column_name,
          time_spine_source=self._time_spine_source,
          time_range_constraint=node.time_range_constraint,
      )
      table_alias_to_instance_set[
          time_spine_data_set_alias
      ] = time_spine_data_set.instance_set
  
      # Figure out which columns correspond to the time dimension that we want to join on.
      input_data_set_metric_time_column_association = (
          input_data_set.column_association_for_time_dimension(
              metric_time_dimension_spec
          )
      )
      input_data_set_metric_time_col = (
          input_data_set_metric_time_column_association.column_name
      )
  
      time_spine_data_set_column_associations = (
          time_spine_data_set.column_association_for_time_dimension(
              metric_time_dimension_spec
          )
      )
      time_spine_data_set_time_dimension_col = (
          time_spine_data_set_column_associations.column_name
      )
  
      annotated_input_data_set = AnnotatedSqlDataSet(
          data_set=input_data_set,
          alias=input_data_set_alias,
          _metric_time_column_name=input_data_set_metric_time_col,
      )
      annotated_time_spine_data_set = AnnotatedSqlDataSet(
          data_set=time_spine_data_set,
          alias=time_spine_data_set_alias,
          _metric_time_column_name=time_spine_data_set_time_dimension_col,
      )
  
      join_desc = SqlQueryPlanJoinBuilder.make_cumulative_metric_time_range_join_description(
          node=node,
          metric_data_set=annotated_input_data_set,
          time_spine_data_set=annotated_time_spine_data_set,
      )
  
      modified_input_instance_set = InstanceSet(
          measure_instances=input_data_set.instance_set.measure_instances,
          dimension_instances=input_data_set.instance_set.dimension_instances,
          entity_instances=input_data_set.instance_set.entity_instances,
          metric_instances=input_data_set.instance_set.metric_instances,
          # we omit the metric time dimension from the right side of the self-join because we need to use
          # the metric time dimension from the right side
          time_dimension_instances=tuple(
              [
                  time_dimension_instance
                  for time_dimension_instance in input_data_set.instance_set.time_dimension_instances
                  if time_dimension_instance.spec
                  != metric_time_dimension_spec
              ]
          ),
      )
      table_alias_to_instance_set[
          input_data_set_alias
      ] = modified_input_instance_set
  
      # The output instances are the same as the input instances.
      output_instance_set = ChangeAssociatedColumns(
          self._column_association_resolver
      ).transform(input_data_set.instance_set)
  
      return SqlDataSet(
          instance_set=output_instance_set,
          sql_select_node=SqlSelectStatementNode(
              description=node.description,
              select_columns=create_select_columns_for_instance_sets(
                  self._column_association_resolver,
                  table_alias_to_instance_set,
              ),
              from_source=time_spine_data_set.sql_select_node,
              from_source_alias=time_spine_data_set_alias,
              joins_descs=(join_desc,),
              group_bys=(),
              where=None,
              order_bys=(),
          ),
      )
  
imports: from __future__ import annotations
  import logging
  from collections import OrderedDict
  from typing import List, Optional, Sequence, Tuple, Union
  from dbt_semantic_interfaces.enum_extension import assert_values_exhausted
  from dbt_semantic_interfaces.protocols.metric import MetricInputMeasure, MetricType
  from dbt_semantic_interfaces.references import MetricModelReference
  from dbt_semantic_interfaces.type_enums.aggregation_type import AggregationType
  from dbt_semantic_interfaces.type_enums.conversion_calculation_type import ConversionCalculationType
  from dbt_semantic_interfaces.validations.unique_valid_name import MetricFlowReservedKeywords
  from metricflow.aggregation_properties import AggregationState
  from metricflow.dag.id_generation import IdGeneratorRegistry
  from metricflow.dataflow.dataflow_plan import AddGeneratedUuidColumnNode, AggregateMeasuresNode, BaseOutput, CombineAggregatedOutputsNode, ComputedMetricsOutput, ComputeMetricsNode, ConstrainTimeRangeNode, DataflowPlanNodeVisitor, FilterElementsNode, JoinConversionEventsNode, JoinOverTimeRangeNode, JoinToBaseOutputNode, JoinToTimeSpineNode, MetricTimeDimensionTransformNode, MinMaxNode, OrderByLimitNode, ReadSqlSourceNode, SemiAdditiveJoinNode, WhereConstraintNode, WriteToResultDataframeNode, WriteToResultTableNode
  from metricflow.dataset.dataset import DataSet
  from metricflow.dataset.sql_dataset import SqlDataSet
  from metricflow.filters.time_constraint import TimeRangeConstraint
  from metricflow.instances import InstanceSet, MetadataInstance, MetricInstance, TimeDimensionInstance
  from metricflow.model.semantic_manifest_lookup import SemanticManifestLookup
  from metricflow.plan_conversion.instance_converters import AddLinkToLinkableElements, AddMetadata, AddMetrics, AliasAggregatedMeasures, ChangeAssociatedColumns, ChangeMeasureAggregationState, ConvertToMetadata, CreateSelectColumnForCombineOutputNode, CreateSelectColumnsForInstances, CreateSelectColumnsWithMeasuresAggregated, CreateSqlColumnReferencesForInstances, FilterElements, FilterLinkableInstancesWithLeadingLink, RemoveMeasures, RemoveMetrics, UpdateMeasureFillNullsWith, create_select_columns_for_instance_sets
  from metricflow.plan_conversion.select_column_gen import SelectColumnSet
  from metricflow.plan_conversion.spec_transforms import CreateColumnAssociations, CreateSelectCoalescedColumnsForLinkableSpecs, SelectOnlyLinkableSpecs
  from metricflow.plan_conversion.sql_join_builder import AnnotatedSqlDataSet, ColumnEqualityDescription, SqlQueryPlanJoinBuilder
  from metricflow.plan_conversion.time_spine import TimeSpineSource
  from metricflow.protocols.sql_client import SqlEngine
  from metricflow.specs.column_assoc import ColumnAssociation, ColumnAssociationResolver, SingleColumnCorrelationKey
  from metricflow.specs.specs import InstanceSpecSet, MeasureSpec, MetadataSpec, MetricSpec, TimeDimensionSpec
  from metricflow.sql.optimizer.optimization_levels import SqlQueryOptimizationLevel, SqlQueryOptimizerConfiguration
  from metricflow.sql.sql_exprs import SqlAggregateFunctionExpression, SqlBetweenExpression, SqlColumnReference, SqlColumnReferenceExpression, SqlComparison, SqlComparisonExpression, SqlDateTruncExpression, SqlExpressionNode, SqlExtractExpression, SqlFunction, SqlFunctionExpression, SqlGenerateUuidExpression, SqlLogicalExpression, SqlLogicalOperator, SqlRatioComputationExpression, SqlStringExpression, SqlStringLiteralExpression, SqlWindowFunction, SqlWindowFunctionExpression, SqlWindowOrderByArgument
  from metricflow.sql.sql_plan import SqlJoinDescription, SqlJoinType, SqlOrderByDescription, SqlQueryPlan, SqlQueryPlanNode, SqlSelectColumn, SqlSelectStatementNode, SqlTableFromClauseNode
  from metricflow.time.time_constants import ISO8601_PYTHON_FORMAT
label_desc: Use image node_id 6 for calling the DataflowToSqlQueryPlanConverter obj's underlying member method code with example usage: obj.visit_join_over_time_range_node(node) and returns: SqlDataSet