docstr: Create function executor
  
  Calls the catalog to insert a function catalog entry.
docstr_tok: ["Create","function","executor","Calls","the","catalog","to","insert","a","function","catalog","entry","."]
code: def exec(self, *args, **kwargs):
      """Create function executor
  
      Calls the catalog to insert a function catalog entry.
      """
      assert (
          self.node.if_not_exists and self.node.or_replace
      ) is False, "OR REPLACE and IF NOT EXISTS can not be both set for CREATE FUNCTION."
  
      overwrite = False
      best_score = False
      train_time = False
      # check catalog if it already has this function entry
      if self.catalog().get_function_catalog_entry_by_name(
          self.node.name
      ):
          if self.node.if_not_exists:
              msg = f"Function {self.node.name} already exists, nothing added."
              yield Batch(pd.DataFrame([msg]))
              return
          elif self.node.or_replace:
              # We use DropObjectExecutor to avoid bookkeeping the code. The drop function should be moved to catalog.
              from evadb.executor.drop_object_executor import (
                  DropObjectExecutor,
              )
  
              drop_executor = DropObjectExecutor(self.db, None)
              try:
                  drop_executor._handle_drop_function(
                      self.node.name, if_exists=False
                  )
              except RuntimeError:
                  pass
              else:
                  overwrite = True
          else:
              msg = f"Function {self.node.name} already exists."
              logger.error(msg)
              raise RuntimeError(msg)
  
      # if it's a type of HuggingFaceModel, override the impl_path
      if string_comparison_case_insensitive(
          self.node.function_type, "HuggingFace"
      ):
          (
              name,
              impl_path,
              function_type,
              io_list,
              metadata,
          ) = self.handle_huggingface_function()
      elif string_comparison_case_insensitive(
          self.node.function_type, "ultralytics"
      ):
          (
              name,
              impl_path,
              function_type,
              io_list,
              metadata,
          ) = self.handle_ultralytics_function()
      elif string_comparison_case_insensitive(
          self.node.function_type, "Ludwig"
      ):
          (
              name,
              impl_path,
              function_type,
              io_list,
              metadata,
              best_score,
              train_time,
          ) = self.handle_ludwig_function()
      elif string_comparison_case_insensitive(
          self.node.function_type, "Sklearn"
      ):
          (
              name,
              impl_path,
              function_type,
              io_list,
              metadata,
              best_score,
              train_time,
          ) = self.handle_sklearn_function()
      elif string_comparison_case_insensitive(
          self.node.function_type, "XGBoost"
      ):
          (
              name,
              impl_path,
              function_type,
              io_list,
              metadata,
              best_score,
              train_time,
          ) = self.handle_xgboost_function()
      elif string_comparison_case_insensitive(
          self.node.function_type, "Forecasting"
      ):
          (
              name,
              impl_path,
              function_type,
              io_list,
              metadata,
          ) = self.handle_forecasting_function()
      else:
          (
              name,
              impl_path,
              function_type,
              io_list,
              metadata,
          ) = self.handle_generic_function()
  
      self.catalog().insert_function_catalog_entry(
          name, impl_path, function_type, io_list, metadata
      )
  
      if overwrite:
          msg = f"Function {self.node.name} overwritten."
      else:
          msg = f"Function {self.node.name} added to the database."
      if best_score and train_time:
          yield Batch(
              pd.DataFrame(
                  [
                      msg,
                      "Validation Score: " + str(best_score),
                      "Training time: " + str(train_time) + " secs.",
                  ]
              )
          )
      else:
          yield Batch(pd.DataFrame([msg]))
  
imports: import contextlib
  import hashlib
  import locale
  import os
  import pickle
  import re
  import time
  from pathlib import Path
  from typing import Dict, List
  import numpy
  import pandas
  from evadb.catalog.catalog_utils import get_metadata_properties
  from evadb.catalog.models.function_catalog import FunctionCatalogEntry
  from evadb.catalog.models.function_io_catalog import FunctionIOCatalogEntry
  from evadb.catalog.models.function_metadata_catalog import FunctionMetadataCatalogEntry
  from evadb.configuration.constants import DEFAULT_SKLEARN_TRAIN_MODEL, DEFAULT_TRAIN_REGRESSION_METRIC, DEFAULT_TRAIN_TIME_LIMIT, DEFAULT_XGBOOST_TASK, SKLEARN_SUPPORTED_MODELS, EvaDB_INSTALLATION_DIR
  from evadb.database import EvaDBDatabase
  from evadb.executor.abstract_executor import AbstractExecutor
  from evadb.functions.decorators.utils import load_io_from_function_decorators
  from evadb.models.storage.batch import Batch
  from evadb.plan_nodes.create_function_plan import CreateFunctionPlan
  from evadb.third_party.huggingface.create import gen_hf_io_catalog_entries
  from evadb.utils.errors import FunctionIODefinitionError
  from evadb.utils.generic_utils import load_function_class_from_file, string_comparison_case_insensitive, try_to_import_flaml_automl, try_to_import_ludwig, try_to_import_neuralforecast, try_to_import_statsforecast, try_to_import_torch, try_to_import_ultralytics
  from evadb.utils.logging_manager import logger
label_desc: Use image node_id 10 for calling the CreateFunctionExecutor obj's underlying member method code with example usage: obj.exec() without return types