/* * 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; }
// 根据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; }
/* * 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; }
/* * 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)); } } }
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; }