code: def _handle_drop_table(self, table_name: str, if_exists: bool):
      if not self.catalog().check_table_exists(table_name):
          err_msg = "Table: {} does not exist".format(table_name)
          if if_exists:
              return Batch(pd.DataFrame([err_msg]))
          else:
              raise ExecutorError(err_msg)
  
      table_obj = self.catalog().get_table_catalog_entry(table_name)
      storage_engine = StorageEngine.factory(self.db, table_obj)
  
      logger.debug(f"Dropping table {table_name}")
      storage_engine.drop(table=table_obj)
  
      for col_obj in table_obj.columns:
          for cache in col_obj.dep_caches:
              self.catalog().drop_function_cache_catalog_entry(cache)
  
      # todo also delete the indexes associated with the table
      assert self.catalog().delete_table_catalog_entry(
          table_obj
      ), "Failed to drop {}".format(table_name)
  
      return Batch(
          pd.DataFrame(
              {"Table Successfully dropped: {}".format(table_name)},
              index=[0],
          )
      )
  
file_path: evadb/evadb/executor/drop_object_executor.py
imports: import pandas
  from evadb.database import EvaDBDatabase
  from evadb.executor.abstract_executor import AbstractExecutor
  from evadb.executor.executor_utils import ExecutorError, handle_vector_store_params
  from evadb.models.storage.batch import Batch
  from evadb.parser.types import ObjectType
  from evadb.plan_nodes.drop_object_plan import DropObjectPlan
  from evadb.storage.storage_engine import StorageEngine
  from evadb.third_party.vector_stores.utils import VectorStoreFactory
  from evadb.utils.logging_manager import logger
label_desc: Use image node_id 3 for calling the DropObjectExecutor obj's underlying member method code with example usage: obj._handle_drop_table(table_name, if_exists) and returns: Batch, Batch