Пример #1
0
/*
 * get_name_from_class_oid - get the name of the class from class oid
 *    return:  the name of the class
 *    class_oid(in) : class oid
 */
static char *
get_name_from_class_oid (OID * class_oid)
{
  MOP class_mop = NULL;
  char *temp_class_name;
  char *result;

  if (!class_oid)
    {
      return NULL;
    }

  class_mop = db_object (class_oid);
  if (class_mop == NULL)
    {
      return NULL;
    }

  temp_class_name = (char *) db_get_class_name (class_mop);
  if (temp_class_name == NULL)
    {
      return NULL;
    }

  result = (char *) malloc (sizeof (char) * (strlen (temp_class_name) + 1));
  if (result == NULL)
    {
      return NULL;
    }

  strcpy (result, temp_class_name);

  return result;
}
Пример #2
0
// 根据query生成一个dbobject
// 从object取sql语句
// 根据结果,构建object
int DatabaseWork::on_mysql_query( DBTask* db_task ) 
{
    // 生成一个db_object
    std::unique_ptr<DBObjectBase> db_object( DBObjectMng::create_dbobject( db_task->table_name_ ) );
    // 读取key
    db_object->write_key( db_task->ar_ );
    // 生成sql语句
    Ar ar;
    if( !db_object->get_sql( ar, DBOP_QUERY ) &&  )
    {
        DBMNG_ERR( "MySQL error gen sql_str failed %s", db_task->table_name_ );
        retuern  -1;
    }
Пример #3
0
/*
 * or_create - 
 *    return:
 *    oid():
 *    conn():
 *    bh_ifs():
 *    ror():
 */
static int
or_create (OID * oid, BIND_HANDLE conn, BH_INTERFACE * bh_ifs, OBJECT_RESULTSET ** ror)
{
  OBJECT_RESULTSET *or;
  int res = NO_ERROR;
  BIND_HANDLE res_h, rm_h;

  assert (oid != NULL);
  assert (ror != NULL);

  /* create structure */
  or = API_CALLOC (1, sizeof (*or));
  if (or == NULL)
    {
      return ER_INTERFACE_NO_MORE_MEMORY;
    }
  or->oid = *oid;
  or->bh_ifs = bh_ifs;
  res = or_res_bind_create (or, &or->res_bind);
  if (res != NO_ERROR)
    {
      API_FREE (or);
      return res;
    }
  res = or_rm_bind_create (or, &or->rm_bind);
  if (res != NO_ERROR)
    {
      or_res_bind_destroy (or->res_bind);
      API_FREE (or);
      return res;
    }
  /* realize handles and setup dependency between them */
  res = bh_ifs->alloc_handle (bh_ifs, (BH_BIND *) or->res_bind, &res_h);
  if (res != NO_ERROR)
    {
      or_res_bind_destroy (or->res_bind);
      or_rm_bind_destroy (or->rm_bind);
      API_FREE (or);
      return res;
    }
  res = bh_ifs->alloc_handle (bh_ifs, (BH_BIND *) or->rm_bind, &rm_h);
  if (res != NO_ERROR)
    {
      bh_ifs->destroy_handle (bh_ifs, res_h);
      or_rm_bind_destroy (or->rm_bind);
      API_FREE (or);
      return res;
    }
  res = bh_ifs->bind_graft (bh_ifs, (BH_BIND *) or->rm_bind, (BH_BIND *) or->res_bind);
  if (res != NO_ERROR)
    {
      bh_ifs->destroy_handle (bh_ifs, res_h);
      bh_ifs->destroy_handle (bh_ifs, rm_h);
      API_FREE (or);
      return res;
    }

  or->obj = db_object (oid);
  if (or->obj == NULL)
    {
      or_destroy (or);
      return ER_INTERFACE_GENERIC;
    }
  or->clz = db_get_class (or->obj);
  if (or->clz == NULL)
    {
      or_destroy (or);
      return ER_INTERFACE_GENERIC;
    }
  /* create object value bind table */
  do
    {
      int i = 0;
      DB_ATTRIBUTE *attrs;

      or->deleted = 0;
      attrs = db_get_attributes (or->obj);
      if (attrs == NULL)
	{
	  or_destroy (or);
	  return ER_INTERFACE_GENERIC;
	}
      or->attrs = attrs;

      while (attrs)
	{
	  i++;
	  attrs = db_attribute_next (attrs);
	}
      or->nattrs = i;
      or->attr_index = API_CALLOC (i, sizeof (DB_ATTRIBUTE *));
      if (or->attr_index == NULL)
	{
	  or_destroy (or);
	  return ER_INTERFACE_NO_MORE_MEMORY;
	}
      attrs = or->attrs;

      i = 0;
      while (attrs)
	{
	  or->attr_index[i] = attrs;
	  attrs = db_attribute_next (attrs);
	  i++;
	}
      or->conn = conn;
      res =
	create_db_value_bind_table (i, or, 0, conn, vt_api_get_index_by_name, vt_api_get_db_value, vt_api_set_db_value,
				    vt_api_init_domain, &or->vt);
      if (res != NO_ERROR)
	{
	  or_destroy (or);
	  return res;
	}
    }
  while (0);

  *ror = or;
  return NO_ERROR;
}
Пример #4
0
/*
 * show_statistics - show the statistics for specified class oids
 *    return:  
 *    class_oid(in) : class oid
 *    unlocked_class(in) : true if the class was not locked
 *    valid_class(in): true if the class was valid 
 *    processed_class(in): true if the class was processed 
 *    total_objects(in): total class objects
 *    failed_objects(in): failed class objects
 *    modified_objects(in): modified class objects
 *    big_objects(in): big class objects
 *    delete_old_repr_flag: delete old representation flag
 *    old_repr_deleted(in): old class representations removed from catalog
 */
static void
show_statistics (OID * class_oid,
		 bool unlocked_class,
		 bool valid_class, bool processed_class,
		 int total_objects, int failed_objects,
		 int modified_objects, int big_objects,
		 bool delete_old_repr_flag, bool old_repr_deleted)
{
  MOP class_mop = NULL;
  char *temp_class_name;

  class_mop = db_object (class_oid);
  if (class_mop == NULL)
    {
      printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			      MSGCAT_UTIL_SET_COMPACTDB,
			      COMPACTDB_MSG_INVALID_CLASS));
      return;
    }

  temp_class_name = (char *) db_get_class_name (class_mop);
  if (temp_class_name == NULL || strlen (temp_class_name) == 0)
    {
      printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			      MSGCAT_UTIL_SET_COMPACTDB,
			      COMPACTDB_MSG_UNKNOWN_CLASS_NAME));
    }
  else
    {
      printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			      MSGCAT_UTIL_SET_COMPACTDB,
			      COMPACTDB_MSG_CLASS), temp_class_name);
    }

  if (!valid_class)
    {
      printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			      MSGCAT_UTIL_SET_COMPACTDB,
			      COMPACTDB_MSG_INVALID_CLASS));

      return;
    }

  if (!processed_class)
    {
      printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			      MSGCAT_UTIL_SET_COMPACTDB,
			      COMPACTDB_MSG_PROCESS_CLASS_ERROR));

    }

  if (!unlocked_class)
    {
      printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			      MSGCAT_UTIL_SET_COMPACTDB,
			      COMPACTDB_MSG_LOCKED_CLASS));
    }

  printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			  MSGCAT_UTIL_SET_COMPACTDB,
			  COMPACTDB_MSG_TOTAL_OBJECTS), total_objects);

  printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			  MSGCAT_UTIL_SET_COMPACTDB,
			  COMPACTDB_MSG_FAILED_OBJECTS), failed_objects);

  printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			  MSGCAT_UTIL_SET_COMPACTDB,
			  COMPACTDB_MSG_MODIFIED_OBJECTS), modified_objects);

  printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			  MSGCAT_UTIL_SET_COMPACTDB,
			  COMPACTDB_MSG_BIG_OBJECTS), big_objects);

  if (delete_old_repr_flag)
    {
      if (old_repr_deleted)
	{
	  printf (msgcat_message (MSGCAT_CATALOG_UTILS,
				  MSGCAT_UTIL_SET_COMPACTDB,
				  COMPACTDB_MSG_REPR_DELETED));
	}
      else
	{
	  printf (msgcat_message (MSGCAT_CATALOG_UTILS,
				  MSGCAT_UTIL_SET_COMPACTDB,
				  COMPACTDB_MSG_REPR_CANT_DELETE));
	}
    }
}
Пример #5
0
static int
do_reclaim_class_addresses (const OID class_oid, char **class_name,
			    bool * const any_class_can_be_referenced,
			    bool * const correctly_processed,
			    bool * const addresses_reclaimed,
			    int *const error_while_processing)
{
  DB_OBJECT *class_mop = NULL;
  DB_OBJECT *parent_mop = NULL;
  SM_CLASS *class_ = NULL;
  SM_CLASS *parent_class_ = NULL;
  int error_code = NO_ERROR;
  int skipped_error_code = NO_ERROR;
  bool do_abort_on_error = true;
  bool can_reclaim_addresses = true;
  LIST_MOPS *lmops = NULL;
  HFID *hfid = NULL;

  assert (!OID_ISNULL (&class_oid));
  assert (any_class_can_be_referenced != NULL);
  assert (correctly_processed != NULL);
  assert (addresses_reclaimed != NULL);
  assert (error_while_processing != NULL);
  assert (class_name != NULL);

  *correctly_processed = false;
  *addresses_reclaimed = false;
  *error_while_processing = NO_ERROR;

  error_code = db_commit_transaction ();
  if (error_code != NO_ERROR)
    {
      goto error_exit;
    }

  error_code = db_set_isolation (TRAN_READ_COMMITTED);
  if (error_code != NO_ERROR)
    {
      goto error_exit;
    }

  /*
   * Trying to force an ISX_LOCK on the root class. It somehow happens that
   * we are left with an IX_LOCK in the end...
   */
  if (locator_fetch_class (sm_Root_class_mop, DB_FETCH_QUERY_WRITE) == NULL)
    {
      error_code = ER_FAILED;
      goto error_exit;
    }

  class_mop = db_object ((OID *) (&class_oid));
  if (class_mop == NULL)
    {
      skipped_error_code = ER_FAILED;
      goto error_exit;
    }

  if (!locator_is_class (class_mop, DB_FETCH_WRITE))
    {
      skipped_error_code = ER_FAILED;
      goto error_exit;
    }

  /*
   * We need an X_LOCK on the class to process as early as possible so that
   * other transactions don't add references to it in the schema.
   */
  class_ = (SM_CLASS *) locator_fetch_class (class_mop, DB_FETCH_WRITE);
  if (class_ == NULL)
    {
      skipped_error_code = er_errid ();
      goto error_exit;
    }

  assert (*class_name == NULL);
  *class_name = strdup (class_->header.name);
  if (*class_name == NULL)
    {
      error_code = ER_FAILED;
      goto error_exit;
    }

  if (class_->partition_of != NULL)
    {
      /*
       * If the current class is a partition of a partitioned class we need
       * to get its parent partitioned table and check for references to its
       * parent too. If table tbl has partition tbl__p__p0, a reference to tbl
       * can point to tbl__p__p0 instances too.
       */
      skipped_error_code = do_get_partition_parent (class_mop, &parent_mop);
      if (skipped_error_code != NO_ERROR)
	{
	  goto error_exit;
	}
      if (parent_mop != NULL)
	{
	  parent_class_ =
	    (SM_CLASS *) locator_fetch_class (parent_mop, DB_FETCH_WRITE);
	  if (parent_class_ == NULL)
	    {
	      skipped_error_code = er_errid ();
	      goto error_exit;
	    }
	}
    }

  skipped_error_code = locator_flush_all_instances (class_mop, true);
  if (skipped_error_code != NO_ERROR)
    {
      goto error_exit;
    }

  if (class_->class_type != SM_CLASS_CT)
    {
      can_reclaim_addresses = false;
    }
  else
    {
      hfid = sm_heap ((MOBJ) class_);
      if (HFID_IS_NULL (hfid))
	{
	  can_reclaim_addresses = false;
	}
    }

  if (class_->flags & SM_CLASSFLAG_SYSTEM)
    {
      /*
       * It should be safe to process system classes also but we skip them for
       * now. Please note that class_instances_can_be_referenced () does not
       * check for references from system classes.
       * If this is ever changed please consider the impact of reusing system
       * objects OIDs.
       */
      can_reclaim_addresses = false;
    }
  else if (class_->flags & SM_CLASSFLAG_REUSE_OID)
    {
      /*
       * Nobody should be able to hold references to reusable OID tables so it
       * should be safe to reclaim their OIDs and pages no matter what.
       */
      can_reclaim_addresses = true;
    }
  else
    {
      if (*any_class_can_be_referenced)
	{
	  /*
	   * Some class attribute has OBJECT or SET OF OBJECT as the domain.
	   * This means it can point to instances of any class so we're not
	   * safe reclaiming OIDs.
	   */
	  can_reclaim_addresses = false;
	}
      else
	{
	  bool class_can_be_referenced = false;

	  /*
	   * IS_LOCK should be enough for what we need but
	   * locator_get_all_class_mops seems to lock the instances with the
	   * lock that it has on their class. So we end up with IX_LOCK on all
	   * classes in the schema...
	   */

	  lmops = locator_get_all_class_mops (DB_FETCH_CLREAD_INSTREAD,
					      is_not_system_class);
	  if (lmops == NULL)
	    {
	      skipped_error_code = ER_FAILED;
	      goto error_exit;
	    }

	  skipped_error_code =
	    class_instances_can_be_referenced (class_mop, parent_mop,
					       &class_can_be_referenced,
					       any_class_can_be_referenced,
					       lmops->mops, lmops->num);
	  if (skipped_error_code != NO_ERROR)
	    {
	      goto error_exit;
	    }
	  /*
	   * If some attribute has OBJECT or the current class as its domain
	   * then it's not safe to reclaim the OIDs as some of the references
	   * might point to deleted objects. We skipped the system classes as
	   * they should not point to any instances of the non-system classes.
	   */
	  can_reclaim_addresses = !class_can_be_referenced &&
	    !*any_class_can_be_referenced;
	  if (lmops != NULL)
	    {
	      /*
	       * It should be safe now to release all the locks we hold on the
	       * schema classes (except for the X_LOCK on the current class).
	       * However, we don't currently have a way of releasing those
	       * locks so we're stuck with them till the end of the current
	       * transaction.
	       */
	      locator_free_list_mops (lmops);
	      lmops = NULL;
	    }
	}
    }

  if (can_reclaim_addresses)
    {
      assert (hfid != NULL && !HFID_IS_NULL (hfid));

      skipped_error_code = heap_reclaim_addresses (hfid);
      if (skipped_error_code != NO_ERROR)
	{
	  goto error_exit;
	}
      *addresses_reclaimed = true;
    }

  error_code = db_commit_transaction ();
  if (error_code != NO_ERROR)
    {
      goto error_exit;
    }

  assert (error_code == NO_ERROR && skipped_error_code == NO_ERROR);
  *correctly_processed = true;
  class_mop = NULL;
  class_ = NULL;
  parent_mop = NULL;
  parent_class_ = NULL;
  return error_code;

error_exit:
  *error_while_processing = skipped_error_code;
  class_mop = NULL;
  class_ = NULL;
  parent_mop = NULL;
  parent_class_ = NULL;
  if (lmops != NULL)
    {
      locator_free_list_mops (lmops);
      lmops = NULL;
    }
  if (do_abort_on_error)
    {
      int tmp_error_code = NO_ERROR;

      if (skipped_error_code == ER_LK_UNILATERALLY_ABORTED ||
	  error_code == ER_LK_UNILATERALLY_ABORTED)
	{
	  tmp_error_code = tran_abort_only_client (false);
	}
      else
	{
	  tmp_error_code = db_abort_transaction ();
	}
      if (tmp_error_code != NO_ERROR)
	{
	  if (error_code == NO_ERROR)
	    {
	      error_code = tmp_error_code;
	    }
	}
    }
  if (skipped_error_code == NO_ERROR && error_code == NO_ERROR)
    {
      error_code = ER_FAILED;
    }
  return error_code;
}