docstr: converter for select statement
  
  Arguments:
      statement {SelectStatement} - - [input select statement]
code: def visit_select(self, statement: SelectStatement):
      """converter for select statement
  
      Arguments:
          statement {SelectStatement} - - [input select statement]
      """
  
      # order of evaluation
      # from, where, group by, select, order by, limit, union
  
      # if there is a table_ref, order by clause and no group by clause, we move all # the function expressions out of projection list to table valued expression.
      # This is done to handle the
      # https://github.com/georgia-tech-db/evadb/issues/1147
      # and https://github.com/georgia-tech-db/evadb/issues/1130.
      # It is a bit ugly but a complete fix would require modifying the binder
  
      col_with_func_exprs = []
  
      if statement.orderby_list and statement.groupby_clause is None:
          projection_cols = []
          for col in statement.target_list:
              if isinstance(col, FunctionExpression):
                  col_with_func_exprs.append(col)
                  # append the TupleValueExpression for the FunctionExpression
                  projection_cols.extend(
                      get_bound_func_expr_outputs_as_tuple_value_expr(
                          col
                      )
                  )
              else:
                  projection_cols.append(col)
  
          # update target list with projection cols
          statement.target_list = projection_cols
  
      table_ref = statement.from_table
      if not table_ref and col_with_func_exprs:
          # if there is no table source, we add a projection node with all the
          # function expressions
          self._visit_projection(col_with_func_exprs)
      else:
          # add col_with_func_exprs to TableValuedExpressions
          for col in col_with_func_exprs:
              tve = TableValuedExpression(col)
              if table_ref:
                  table_ref = TableRef(
                      JoinNode(
                          table_ref,
                          TableRef(tve, alias=col.alias),
                          join_type=JoinType.LATERAL_JOIN,
                      )
                  )
  
          statement.from_table = table_ref
  
      if table_ref is not None:
          self.visit_table_ref(table_ref)
  
          # Filter Operator
          predicate = statement.where_clause
          if predicate is not None:
              self._visit_select_predicate(predicate)
  
          # TODO ACTION: Group By
  
          if statement.groupby_clause is not None:
              self._visit_groupby(statement.groupby_clause)
  
      if statement.orderby_list is not None:
          self._visit_orderby(statement.orderby_list)
  
      if statement.limit_count is not None:
          self._visit_limit(statement.limit_count)
  
      if statement.target_list is not None:
          self._visit_projection(statement.target_list)
  
      # union
      if statement.union_link is not None:
          self._visit_union(statement.union_link, statement.union_all)
  
imports: from evadb.binder.binder_utils import get_bound_func_expr_outputs_as_tuple_value_expr
  from evadb.expression.abstract_expression import AbstractExpression
  from evadb.expression.function_expression import FunctionExpression
  from evadb.optimizer.operators import LogicalCreate, LogicalCreateFunction, LogicalCreateIndex, LogicalDelete, LogicalDropObject, LogicalExplain, LogicalExtractObject, LogicalFilter, LogicalFunctionScan, LogicalGet, LogicalGroupBy, LogicalInsert, LogicalJoin, LogicalLimit, LogicalLoadData, LogicalOrderBy, LogicalProject, LogicalQueryDerivedGet, LogicalRename, LogicalSample, LogicalShow, LogicalUnion
  from evadb.optimizer.optimizer_utils import column_definition_to_function_io, metadata_definition_to_function_metadata
  from evadb.parser.create_function_statement import CreateFunctionStatement
  from evadb.parser.create_index_statement import CreateIndexStatement
  from evadb.parser.create_statement import CreateTableStatement
  from evadb.parser.delete_statement import DeleteTableStatement
  from evadb.parser.drop_object_statement import DropObjectStatement
  from evadb.parser.explain_statement import ExplainStatement
  from evadb.parser.insert_statement import InsertTableStatement
  from evadb.parser.load_statement import LoadDataStatement
  from evadb.parser.rename_statement import RenameTableStatement
  from evadb.parser.select_statement import SelectStatement
  from evadb.parser.show_statement import ShowStatement
  from evadb.parser.statement import AbstractStatement
  from evadb.parser.table_ref import JoinNode, TableRef, TableValuedExpression
  from evadb.parser.types import FunctionType, JoinType
  from evadb.utils.logging_manager import logger
label_desc: Use image node_id 3 for calling the StatementToPlanConverter obj's underlying member method code with example usage: obj.visit_select(statement) without return types