class_docstr: Visits the SQL query plan to simplify sub-queries. On each visit, return a simplfied node.
class_docstr_tok: ["Visits","the","SQL","query","plan","to","simplify","sub-queries",".","On","each","visit",",","return","a","simplfied","node","."]
code: def visit_select_statement_node(
      self, node: SqlSelectStatementNode
  ) -> SqlQueryPlanNode:  # noqa: D
      node_with_reduced_parents = self._reduce_parents(node)
  
      if not self._reduce_is_possible(node_with_reduced_parents):
          return node_with_reduced_parents
  
      assert len(node_with_reduced_parents.parent_nodes) == 1
      parent_node = node_with_reduced_parents.parent_nodes[0]
      parent_select_node = parent_node.as_select_node
      assert parent_select_node
  
      # At this point, the query should look similar to
      #
      #     SELECT b.foo, b.baz
      #     FROM (
      #       SELECT a.foo, a.baz FROM bar a
      #       LIMIT 10
      #     ) b
      #     ORDER by b.baz
      #     LIMIT 1
  
      # The order by in the parent doesn't matter since the order by in this node will "overwrite" the order in the
      # parent as long as the parent has no limits.
      new_order_by: List[SqlOrderByDescription] = []
      if node_with_reduced_parents.order_bys:
          for order_by_item in node_with_reduced_parents.order_bys:
              order_by_item_expr = (
                  order_by_item.expr.as_column_reference_expression
              )
              assert order_by_item_expr
  
              # Re-write the order by as a column expression that references the table alias
              table_alias_in_parent = (
                  SqlSubQueryReducerVisitor._find_matching_table_alias(
                      parent_select_node,
                      order_by_item_expr.col_ref.column_name,
                  )
              )
              if not table_alias_in_parent:
                  return node_with_reduced_parents
              new_order_by.append(
                  SqlOrderByDescription(
                      expr=SqlColumnReferenceExpression(
                          SqlColumnReference(
                              table_alias=table_alias_in_parent,
                              column_name=order_by_item_expr.col_ref.column_name,
                          )
                      ),
                      desc=order_by_item.desc,
                  )
              )
  
      # The limit should be the min of this SELECT limit and the parent SELECT limit.
      new_limit: Optional[int] = node_with_reduced_parents.limit
      if new_limit is None:
          new_limit = parent_select_node.limit
      elif parent_select_node.limit is not None:
          new_limit = min(new_limit, parent_select_node.limit)
  
      return SqlSelectStatementNode(
          description="\n".join(
              [
                  parent_select_node.description,
                  node_with_reduced_parents.description,
              ]
          ),
          select_columns=parent_select_node.select_columns,
          from_source=parent_select_node.from_source,
          from_source_alias=parent_select_node.from_source_alias,
          joins_descs=parent_select_node.join_descs,
          group_bys=parent_select_node.group_bys,
          order_bys=tuple(new_order_by),
          where=parent_select_node.where,
          limit=new_limit,
          distinct=parent_select_node.distinct,
      )
  
file_path: metricflow/metricflow/sql/optimizer/sub_query_reducer.py
imports: from __future__ import annotations
  import logging
  from typing import List, Optional
  from metricflow.sql.optimizer.sql_query_plan_optimizer import SqlQueryPlanOptimizer
  from metricflow.sql.sql_exprs import SqlColumnReference, SqlColumnReferenceExpression
  from metricflow.sql.sql_plan import SqlJoinDescription, SqlOrderByDescription, SqlQueryPlanNode, SqlQueryPlanNodeVisitor, SqlSelectQueryFromClauseNode, SqlSelectStatementNode, SqlTableFromClauseNode
label_desc: Use image node_id 4 for calling the SqlSubQueryReducerVisitor obj's underlying member method code with example usage: obj.visit_select_statement_node(node) and returns: SqlSelectStatementNode, node_with_reduced_parents, node_with_reduced_parents