class_docstr: The Discord Table implementation
class_docstr_tok: ["The","Discord","Table","implementation"]
docstr: Selects data from the Discord channel.
  
  Parameters
  ----------
  query : ast.Select
     Given SQL SELECT query.
  
  Returns
  -------
  Response
      Response object representing collected data from Discord.
docstr_tok: ["Selects","data","from","the","Discord","channel",".","Parameters","--","--","--","--","--","query",":","ast.Select","Given","SQL","SELECT","query",".","Returns","--","--","--","-","Response","Response","object","representing","collected","data","from","Discord","."]
code: def select(self, query: ast.Select) -> Response:
      """Selects data from the Discord channel.
  
      Parameters
      ----------
      query : ast.Select
         Given SQL SELECT query.
  
      Returns
      -------
      Response
          Response object representing collected data from Discord.
      """
  
      conditions = extract_comparison_conditions(query.where)
  
      params = {}
      filters = []
      user_filter_flag = channel_filter_flag = False
      for op, arg1, arg2 in conditions:
          if op == "or":
              raise NotImplementedError("OR is not supported")
          if arg1 == "timestamp":
              if op == ">":
                  params["after"] = arg2
              elif op == "<":
                  params["before"] = arg2
              else:
                  raise NotImplementedError(
                      f"Unsupported operator {op} for timestamp"
                  )
  
          elif arg1 in [
              "author_id",
              "author_username",
              "author_global_name",
          ]:
              if user_filter_flag:
                  raise NotImplementedError(
                      "Multiple user filters are not supported"
                  )
              user_filter_flag = True
  
              if op != "=":
                  raise NotImplementedError(
                      f"Unsupported operator {op} for {arg1}"
                  )
  
              # if arg1 == 'author_id':
              #     filters.append(lambda x: x.author.id == int(arg2))
              # elif arg1 == 'author_username':
              #     filters.append(lambda x: x.author.username == arg2)
              # elif arg1 == 'author_global_name':
              #     filters.append(lambda x: x.author.global_name == arg2)
  
          elif arg1 == "channel_id":
              if op != "=":
                  raise NotImplementedError(
                      f"Unsupported operator {op} for {arg1}"
                  )
              channel_filter_flag = True
              params["channel_id"] = int(arg2)
  
          else:
              filters.append([op, arg1, arg2])
  
      if query.limit is not None:
          params["limit"] = query.limit
      else:
          params["limit"] = 100
  
      if not channel_filter_flag:
          raise NotImplementedError("Channel filter is required")
  
      result = self.handler.call_discord_api(
          "get_messages", params=params, filters=filters
      )
  
      # filter targets
      columns = []
      for target in query.targets:
          if isinstance(target, ast.Star):
              columns = []
              break
          elif isinstance(target, ast.Identifier):
              columns.append(target.parts[-1])
          else:
              raise NotImplementedError
  
      if len(columns) == 0:
          columns = self.get_columns()
  
      # columns to lower case
      columns = [name.lower() for name in columns]
  
      if len(result) == 0:
          result = pd.DataFrame([], columns=columns)
      else:
          # add absent columns
          for col in set(columns) & set(result.columns) ^ set(columns):
              result[col] = None
  
          # filter by columns
          result = result[columns]
      return result
  
file_path: mindsdb/mindsdb/integrations/handlers/discord_handler/discord_tables.py
imports: import pandas
  from typing import Text, List, Dict, Any
  from mindsdb_sql.parser import ast
  from mindsdb.integrations.libs.api_handler import APITable
  from mindsdb.integrations.utilities.sql_utils import extract_comparison_conditions
  from mindsdb.integrations.libs.response import HandlerResponse
  from mindsdb.integrations.handlers.utilities.query_utilities.insert_query_utilities import INSERTQueryParser
  from mindsdb.utilities import log
label_desc: Use image node_id 2 for calling the MessagesTable obj's underlying member method code with example usage: obj.select(query) and returns: result