class_docstr: Helper class for constructing various join components in a SqlQueryPlan.
docstr: Make a join description to connect a cumulative metric input to a time spine dataset.
  
  Cumulative metrics must be joined against a time spine in a backward-looking fashion, with
  a range determined by a time window (delta against metric_time) and optional cumulative grain.
docstr_tok: ["Make","a","join","description","to","connect","a","cumulative","metric","input","to","a","time","spine","dataset",".","Cumulative","metrics","must","be","joined","against","a","time","spine","in","a","backward-looking","fashion",",","with","a","range","determined","by","a","time","window","(","delta","against","metric_time",")","and","optional","cumulative","grain","."]
code: def make_cumulative_metric_time_range_join_description(
      node: JoinOverTimeRangeNode,
      metric_data_set: AnnotatedSqlDataSet,
      time_spine_data_set: AnnotatedSqlDataSet,
  ) -> SqlJoinDescription:
      """Make a join description to connect a cumulative metric input to a time spine dataset.
  
      Cumulative metrics must be joined against a time spine in a backward-looking fashion, with
      a range determined by a time window (delta against metric_time) and optional cumulative grain.
      """
      cumulative_join_condition = SqlQueryPlanJoinBuilder._make_time_range_window_join_condition(
          base_data_set=metric_data_set,
          time_comparison_dataset=time_spine_data_set,
          window=node.window,
          grain_to_date=node.grain_to_date,
      )
  
      return SqlJoinDescription(
          right_source=metric_data_set.data_set.sql_select_node,
          right_source_alias=metric_data_set.alias,
          on_condition=cumulative_join_condition,
          join_type=SqlJoinType.INNER,
      )
  
imports: from __future__ import annotations
  from dataclasses import dataclass
  from typing import List, Optional, Sequence, Tuple
  from dbt_semantic_interfaces.protocols.metric import MetricTimeWindow
  from dbt_semantic_interfaces.type_enums.time_granularity import TimeGranularity
  from metricflow.assert_one_arg import assert_exactly_one_arg_set
  from metricflow.dataflow.dataflow_plan import JoinConversionEventsNode, JoinDescription, JoinOverTimeRangeNode, JoinToTimeSpineNode
  from metricflow.dataset.sql_dataset import SqlDataSet
  from metricflow.plan_conversion.sql_expression_builders import make_coalesced_expr
  from metricflow.sql.sql_exprs import SqlColumnReference, SqlColumnReferenceExpression, SqlComparison, SqlComparisonExpression, SqlDateTruncExpression, SqlIsNullExpression, SqlLogicalExpression, SqlLogicalOperator, SqlSubtractTimeIntervalExpression
  from metricflow.sql.sql_plan import SqlExpressionNode, SqlJoinDescription, SqlJoinType, SqlSelectStatementNode
label_desc: Use image node_id 9 for calling the SqlQueryPlanJoinBuilder obj's underlying member method code with example usage: obj.make_cumulative_metric_time_range_join_description(node, metric_data_set, time_spine_data_set) and returns: SqlJoinDescription