class_docstr: Renders an SQL plan following ANSI SQL.
class_docstr_tok: ["Renders","an","SQL","plan","following","ANSI","SQL","."]
docstr: Convert the select columns into a "SELECT" section.
  
  e.g.
  SELECT
    1 AS bookings
    , listing_id AS listing
    ...
  
  Returns a tuple of the "SELECT" section as a string and the associated execution parameters.
docstr_tok: ["Convert","the","select","columns","into","a","``","SELECT","''","section",".","e.g",".","SELECT","1","AS","bookings",",","listing_id","AS","listing","...","Returns","a","tuple","of","the","``","SELECT","''","section","as","a","string","and","the","associated","execution","parameters","."]
code: def _render_select_columns_section(
      self,
      select_columns: Sequence[SqlSelectColumn],
      num_parents: int,
      distinct: bool,
  ) -> Tuple[str, SqlBindParameters]:
      """Convert the select columns into a "SELECT" section.
  
      e.g.
      SELECT
        1 AS bookings
        , listing_id AS listing
        ...
  
      Returns a tuple of the "SELECT" section as a string and the associated execution parameters.
      """
      params = SqlBindParameters()
      select_section_lines = [
          "SELECT DISTINCT" if distinct else "SELECT"
      ]
      first_column = True
      for select_column in select_columns:
          expr_rendered = self.EXPR_RENDERER.render_sql_expr(
              select_column.expr
          )
          # Merge all execution parameters together. Similar pattern follows below.
          params = params.combine(expr_rendered.bind_parameters)
  
          column_select_str = (
              f"{expr_rendered.sql} AS {select_column.column_alias}"
          )
  
          # For cases where the alias is the same as column like "src.foo AS foo", just render it as "src.foo"
          # SQLite throws an ambiguous column error with something like
          #
          # SELECT a.ds
          # FROM fct_bookings a
          # JOIN dim_users b
          # on a.ds = b.ds
          #
          # so don't do this if it has joins.
          if (
              num_parents <= 1
              and select_column.expr.as_column_reference_expression
          ):
              column_reference = (
                  select_column.expr.as_column_reference_expression.col_ref
              )
              if (
                  column_reference.column_name
                  == select_column.column_alias
              ):
                  column_select_str = expr_rendered.sql
  
          if first_column:
              first_column = False
              select_section_lines.append(
                  f"{self.INDENT}{column_select_str}"
              )
          else:
              select_section_lines.append(
                  f"{self.INDENT}, {column_select_str}"
              )
  
      return "\n".join(select_section_lines), params
  
imports: from __future__ import annotations
  import logging
  import textwrap
  from abc import ABC, abstractmethod
  from dataclasses import dataclass
  from typing import List, Optional, Sequence, Tuple
  from metricflow.sql.render.expr_renderer import DefaultSqlExpressionRenderer, SqlExpressionRenderer, SqlExpressionRenderResult
  from metricflow.sql.sql_bind_parameters import SqlBindParameters
  from metricflow.sql.sql_plan import SqlJoinDescription, SqlQueryPlan, SqlQueryPlanNode, SqlQueryPlanNodeVisitor, SqlSelectColumn, SqlSelectQueryFromClauseNode, SqlSelectStatementNode, SqlTableFromClauseNode
label_desc: Use image node_id 1 for calling the DefaultSqlQueryPlanRenderer obj's underlying member method code with example usage: obj._render_select_columns_section(select_columns, num_parents, distinct) and returns: str,  params