class_docstr: This context is used to store information that is useful during the process of binding a statement (such as a SELECT statement) to the catalog. It stores the following information:
  
  Args:
      `_table_alias_map`: Maintains a mapping from table_alias to corresponding
      catalog table entry
      `_derived_table_alias_map`: Maintains a mapping from derived table aliases,
      such as subqueries or function expressions, to column alias maps for all the
      corresponding projected columns. For example, in the following queries, the
      `_derived_table_alias_map` attribute would contain:
  
      `Select * FROM (SELECT id1, id2 FROM table) AS A` :
          `{A: {id1: table.col1, id2: table.col2}}`
      `Select * FROM video LATERAL JOIN func AS T(a, b)` :
          `{T: {a: func.obj1, b:func.obj2}}`
docstr: Find the binded column object
  Arguments:
      col_name (str): column name
      alias (str): alias name
  
  Returns:
      A tuple of alias and column object
docstr_tok: ["Find","the","binded","column","object","Arguments",":","col_name","(","str",")",":","column","name","alias","(","str",")",":","alias","name","Returns",":","A","tuple","of","alias","and","column","object"]
code: def get_binded_column(
      self, col_name: str, alias: str = None
  ) -> Tuple[str, CatalogColumnType]:
      """
      Find the binded column object
      Arguments:
          col_name (str): column name
          alias (str): alias name
  
      Returns:
          A tuple of alias and column object
      """
  
      # binder is case insensitive
      col_name = col_name.lower()
  
      def raise_error():
          all_columns = sorted(
              list(
                  set(
                      [
                          col
                          for _, col in self._get_all_alias_and_col_name()
                      ]
                  )
              )
          )
          res = process.extractOne(col_name, all_columns)
          if res is not None:
              guess_column, _ = res
              err_msg = f"Cannot find column {col_name}. Did you mean {guess_column}? The feasible columns are {all_columns}."
          else:
              err_msg = f"Cannot find column {col_name}. There are no feasible columns."
          logger.error(err_msg)
          raise BinderError(err_msg)
  
      if not alias:
          alias, col_obj = self._search_all_alias_maps(col_name)
      else:
          # search in all alias maps
          col_obj = self._check_table_alias_map(alias, col_name)
          if not col_obj:
              col_obj = self._check_derived_table_alias_map(
                  alias, col_name
              )
  
      if col_obj:
          return alias, col_obj
  
      raise_error()
  
imports: from typing import Callable, Dict, List, Tuple, Union
  from thefuzz import process
  from evadb.binder.binder_utils import BinderError, check_data_source_and_table_are_valid, create_table_catalog_entry_for_data_source
  from evadb.catalog.catalog_type import TableType
  from evadb.catalog.models.column_catalog import ColumnCatalogEntry
  from evadb.catalog.models.function_io_catalog import FunctionIOCatalogEntry
  from evadb.catalog.models.table_catalog import TableCatalogEntry
  from evadb.expression.function_expression import FunctionExpression
  from evadb.expression.tuple_value_expression import TupleValueExpression
  from evadb.third_party.databases.interface import get_database_handler
  from evadb.utils.logging_manager import logger
label_desc: Use image node_id 5 for calling the StatementBinderContext obj's underlying member method code with example usage: obj.get_binded_column(col_name, alias) and returns: alias,  col_obj