/* * pt_set_domain_class() - set SM_DOMAIN's class field * return: none * dom(out): an SM_DOMAIN * nam(in): an entity name * virt(in): */ static void pt_set_domain_class (SM_DOMAIN * dom, const PT_NODE * nam, const DB_OBJECT * virt) { if (!dom || !nam || nam->node_type != PT_NAME) return; dom->type = PR_TYPE_FROM_ID (DB_TYPE_OBJECT); if (virt != NULL) { dom->class_mop = (DB_OBJECT *) virt; } else { if (nam->info.name.db_object != NULL) { dom->class_mop = nam->info.name.db_object; COPY_OID (&dom->class_oid, &(dom->class_mop->oid_info.oid)); } else { dom->class_mop = db_find_class (nam->info.name.original); if (dom->class_mop != NULL) { COPY_OID (&dom->class_oid, &(dom->class_mop->oid_info.oid)); } } } }
/* * disk_insert_instance - This inserts a new object in the database given a * "descriptor" for the object. * return: NO_ERROR if successful, error code otherwise * classop(in): class object * obj(in): object description * oid(in): oid of the destination */ int disk_insert_instance (MOP classop, DESC_OBJ * obj, OID * oid) { int error = NO_ERROR; HFID *hfid; int newsize; bool has_indexes; Diskrec->length = 0; if (desc_obj_to_disk (obj, Diskrec, &has_indexes)) { /* make the record larger */ newsize = -Diskrec->length + DB_PAGESIZE; free_recdes (Diskrec); Diskrec = alloc_recdes (newsize); /* try one more time */ if (Diskrec == NULL || desc_obj_to_disk (obj, Diskrec, &has_indexes) != 0) { error = ER_LDR_CANT_TRANSFORM; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0); } } if (!error) { hfid = get_class_heap (classop, obj->class_); if (hfid == NULL) { assert (er_errid () != NO_ERROR); error = er_errid (); } else { HEAP_OPERATION_CONTEXT context; /* set up context */ heap_create_insert_context (&context, hfid, WS_OID (classop), Diskrec, NULL, false); /* oid is set here as a side effect */ if (heap_insert_logical (NULL, &context) != NO_ERROR) { assert (er_errid () != NO_ERROR); error = er_errid (); } else if (has_indexes) { COPY_OID (oid, &context.res_oid); error = update_indexes (WS_OID (classop), oid, Diskrec); } else { COPY_OID (oid, &context.res_oid); } } } return (error); }
static int cursor_prefetch_first_hidden_oid (CURSOR_ID * cursor_id_p) { char *tuple_p; OID *current_oid_p; QFILE_TUPLE current_tuple; int tupel_count, oid_index = 0, current_tuple_length, i; DB_TYPE type; /* set tuple count and point to the first tuple */ tupel_count = QFILE_GET_TUPLE_COUNT (cursor_id_p->buffer); current_tuple = cursor_id_p->buffer + QFILE_PAGE_HEADER_SIZE; oid_index = 0; /* * search through the current buffer to store interesting OIDs * in the oid_set area, eliminating duplicates. */ for (i = 0; i < tupel_count; i++) { current_tuple_length = QFILE_GET_TUPLE_LENGTH (current_tuple); /* fetch first OID */ type = cursor_id_p->list_id.type_list.domp[0]->type->id; tuple_p = (char *) current_tuple + QFILE_TUPLE_LENGTH_SIZE; if (QFILE_GET_TUPLE_VALUE_FLAG (tuple_p) != V_BOUND) { continue; } current_oid_p = cursor_get_oid_from_tuple (tuple_p, type); if (current_oid_p && oid_index < cursor_id_p->oid_ent_count) { COPY_OID (&cursor_id_p->oid_set[oid_index], current_oid_p); oid_index++; } /* move to next tuple */ current_tuple = (char *) current_tuple + current_tuple_length; } return cursor_fetch_oids (cursor_id_p, oid_index, cursor_id_p->prefetch_lock_mode, (cursor_id_p->prefetch_lock_mode == DB_FETCH_WRITE) ? DB_FETCH_QUERY_WRITE : DB_FETCH_QUERY_READ); }
/* * compactdb_start - Compact classes * return: error code * verbose_flag(in): * delete_old_repr_flag(in): delete old class representations from catalog * input_filename(in): classes file name * input_class_names(in): classes list * input_class_length(in): classes list length * max_processed_space(in): maximum space to process for one iteration */ static int compactdb_start (bool verbose_flag, bool delete_old_repr_flag, char *input_filename, char **input_class_names, int input_class_length, int max_processed_space, int instance_lock_timeout, int class_lock_timeout, DB_TRAN_ISOLATION tran_isolation) { int status = NO_ERROR; OID **class_oids = NULL, *next_oid = NULL; int i, num_classes = 0; LIST_MOPS *class_table = NULL; OID last_processed_class_oid, last_processed_oid; int *total_objects = NULL, *iteration_total_objects = NULL; int *failed_objects = NULL, *iteration_failed_objects = NULL; int *modified_objects = NULL, *iteration_modified_objects = NULL; char *incomplete_processing = NULL; int *big_objects = NULL, *iteration_big_objects = NULL; int *initial_last_repr = NULL; MOP *class_mops = NULL; int last_completed_class_index, temp_index; int num_class_mops = 0; SM_CLASS *class_ptr = NULL; int num_classes_fully_compacted = 0; char *class_name = NULL; MOP *processed_class_mops = NULL; if (input_filename && input_class_names && input_class_length > 0) { return ER_FAILED; } status = compact_db_start (); if (status != NO_ERROR) { if (status == ER_COMPACTDB_ALREADY_STARTED) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_ALREADY_STARTED)); } return ER_FAILED; } tran_reset_wait_times ((float) class_lock_timeout); if (input_class_names && input_class_length > 0) { status = get_class_mops (input_class_names, input_class_length, &class_mops, &num_class_mops); if (status != NO_ERROR) { goto error; } } else if (input_filename) { status = get_class_mops_from_file (input_filename, &class_mops, &num_class_mops); if (status != NO_ERROR) { goto error; } } else { class_table = locator_get_all_mops (sm_Root_class_mop, DB_FETCH_QUERY_READ); if (!class_table) { status = ER_FAILED; goto error; } class_mops = class_table->mops; num_class_mops = class_table->num; } class_oids = (OID **) malloc (DB_SIZEOF (OID *) * (num_class_mops)); if (class_oids == NULL) { status = ER_FAILED; goto error; } for (i = 0; i < num_class_mops; i++) { class_oids[i] = NULL; } processed_class_mops = (DB_OBJECT **) malloc (DB_SIZEOF (DB_OBJECT *) * (num_class_mops)); if (processed_class_mops == NULL) { status = ER_FAILED; goto error; } for (i = 0; i < num_class_mops; i++) { processed_class_mops[i] = NULL; } num_classes = 0; for (i = 0; i < num_class_mops; i++) { ws_find (class_mops[i], (MOBJ *) & class_ptr); if (class_ptr == NULL) { continue; } if (class_ptr->class_type != SM_CLASS_CT) { continue; } class_oids[num_classes] = ws_oid (class_mops[i]); if (class_oids[num_classes] != NULL) { processed_class_mops[num_classes] = class_mops[i]; num_classes++; } } if (num_classes == 0) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_NOTHING_TO_PROCESS)); goto error; } total_objects = (int *) malloc (num_classes * sizeof (int)); if (total_objects == NULL) { status = ER_FAILED; goto error; } iteration_total_objects = (int *) malloc (num_classes * sizeof (int)); if (iteration_total_objects == NULL) { status = ER_FAILED; goto error; } failed_objects = (int *) malloc (num_classes * sizeof (int)); if (failed_objects == NULL) { status = ER_FAILED; goto error; } iteration_failed_objects = (int *) malloc (num_classes * sizeof (int)); if (iteration_failed_objects == NULL) { status = ER_FAILED; goto error; } modified_objects = (int *) malloc (num_classes * sizeof (int)); if (modified_objects == NULL) { status = ER_FAILED; goto error; } iteration_modified_objects = (int *) malloc (num_classes * sizeof (int)); if (iteration_modified_objects == NULL) { status = ER_FAILED; goto error; } big_objects = (int *) malloc (num_classes * sizeof (int)); if (big_objects == NULL) { status = ER_FAILED; goto error; } iteration_big_objects = (int *) malloc (num_classes * sizeof (int)); if (iteration_big_objects == NULL) { status = ER_FAILED; goto error; } initial_last_repr = (int *) malloc (num_classes * sizeof (int)); if (initial_last_repr == NULL) { status = ER_FAILED; goto error; } incomplete_processing = (char *) malloc (num_classes * sizeof (char)); if (incomplete_processing == NULL) { status = ER_FAILED; goto error; } for (i = 0; i < num_classes; i++) { total_objects[i] = 0; failed_objects[i] = 0; modified_objects[i] = 0; big_objects[i] = 0; incomplete_processing[i] = 0; initial_last_repr[i] = NULL_REPRID; } for (i = 0; i < num_class_mops; i++) { status = locator_flush_all_instances (class_mops[i], true); if (status != NO_ERROR) { goto error; } } status = db_commit_transaction (); if (status != NO_ERROR) { goto error; } COPY_OID (&last_processed_class_oid, class_oids[0]); OID_SET_NULL (&last_processed_oid); temp_index = -1; last_completed_class_index = -1; if (verbose_flag) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_PASS1)); } while (true) { status = db_set_isolation (tran_isolation); if (status != NO_ERROR) { if (verbose_flag) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_ISOLATION_LEVEL_FAILURE)); } status = ER_FAILED; goto error; } status = boot_compact_classes (class_oids, num_classes, max_processed_space, instance_lock_timeout * 1000, class_lock_timeout * 1000, delete_old_repr_flag, &last_processed_class_oid, &last_processed_oid, iteration_total_objects, iteration_failed_objects, iteration_modified_objects, iteration_big_objects, initial_last_repr); if (OID_ISNULL (&last_processed_class_oid)) { temp_index = num_classes; } else { temp_index = find_oid (&last_processed_class_oid, class_oids, num_classes); } switch (status) { case NO_ERROR: if (delete_old_repr_flag && temp_index - 1 > last_completed_class_index) { for (i = last_completed_class_index + 1; i < temp_index; i++) { if (initial_last_repr[i] == COMPACTDB_REPR_DELETED) { sm_destroy_representations (processed_class_mops[i]); } } } status = db_commit_transaction (); if (status != NO_ERROR) { goto error; } break; case ER_LK_UNILATERALLY_ABORTED: status = tran_abort_only_client (false); if (status != NO_ERROR) { goto error; } break; case ER_FAILED: status = db_abort_transaction (); if (status != NO_ERROR) { goto error; } break; default: db_abort_transaction (); status = ER_FAILED; goto error; } for (i = 0; i < num_classes; i++) { if (iteration_total_objects[i] >= 0) { total_objects[i] += iteration_total_objects[i]; failed_objects[i] += iteration_failed_objects[i]; modified_objects[i] += iteration_modified_objects[i]; big_objects[i] += iteration_big_objects[i]; } else { incomplete_processing[i] = iteration_total_objects[i]; } } if (temp_index - 1 > last_completed_class_index) { for (i = last_completed_class_index + 1; i < temp_index; i++) { status = db_set_isolation (tran_isolation); if (status != NO_ERROR) { if (verbose_flag) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_ISOLATION_LEVEL_FAILURE)); } status = ER_FAILED; goto error; } tran_reset_wait_times ((float) class_lock_timeout); show_statistics (class_oids[i], incomplete_processing[i] != COMPACTDB_LOCKED_CLASS, incomplete_processing[i] != COMPACTDB_INVALID_CLASS, incomplete_processing[i] != COMPACTDB_UNPROCESSED_CLASS, total_objects[i], failed_objects[i], modified_objects[i], big_objects[i], delete_old_repr_flag, initial_last_repr[i] == COMPACTDB_REPR_DELETED); db_commit_transaction (); } last_completed_class_index = temp_index - 1; } if (OID_ISNULL (&last_processed_class_oid)) { break; } } if (verbose_flag) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_PASS2)); } status = do_reclaim_addresses (class_oids, num_classes, &num_classes_fully_compacted, verbose_flag, (float) class_lock_timeout); if (status != NO_ERROR) { goto error; } if (verbose_flag) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_PASS3)); } for (i = 0; i < num_classes; i++) { status = db_set_isolation (tran_isolation); if (status != NO_ERROR) { if (verbose_flag) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_ISOLATION_LEVEL_FAILURE)); } status = ER_FAILED; goto error; } tran_reset_wait_times ((float) class_lock_timeout); status = boot_heap_compact (class_oids[i]); switch (status) { case NO_ERROR: status = db_commit_transaction (); if (status != NO_ERROR) { goto error; } break; case ER_LK_UNILATERALLY_ABORTED: status = tran_abort_only_client (false); if (status != NO_ERROR) { goto error; } break; default: status = db_abort_transaction (); if (status != NO_ERROR) { goto error; } break; } class_name = get_name_from_class_oid (class_oids[i]); if (class_name == NULL) { 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), class_name); } if (status != NO_ERROR) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_HEAP_COMPACT_FAILED)); } else { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_HEAP_COMPACT_SUCCEEDED)); } if (class_name) { free (class_name); class_name = NULL; } db_commit_transaction (); } error: if (class_oids) { free_and_init (class_oids); } if (processed_class_mops) { free_and_init (processed_class_mops); } if (total_objects) { free_and_init (total_objects); } if (iteration_total_objects) { free_and_init (iteration_total_objects); } if (failed_objects) { free_and_init (failed_objects); } if (iteration_failed_objects) { free_and_init (iteration_failed_objects); } if (modified_objects) { free_and_init (modified_objects); } if (iteration_modified_objects) { free_and_init (iteration_modified_objects); } if (big_objects) { free_and_init (big_objects); } if (iteration_big_objects) { free_and_init (iteration_big_objects); } if (initial_last_repr) { free_and_init (initial_last_repr); } if (incomplete_processing) { free_and_init (incomplete_processing); } if (class_table) { locator_free_list_mops (class_table); } else { if (class_mops) { for (i = 0; i < num_class_mops; i++) { class_mops[i] = NULL; } free_and_init (class_mops); } } compact_db_stop (); return status; }
static int cursor_prefetch_column_oids (CURSOR_ID * cursor_id_p) { char *tuple_p; OID *current_oid_p; QFILE_TUPLE current_tuple; int tuple_count, oid_index = 0, current_tuple_length; int j, tuple_index, col_index, col_num; DB_TYPE type; /* set tuple count and point to the first tuple */ tuple_count = QFILE_GET_TUPLE_COUNT (cursor_id_p->buffer); current_tuple = cursor_id_p->buffer + QFILE_PAGE_HEADER_SIZE; oid_index = 0; for (tuple_index = 0; tuple_index < tuple_count; tuple_index++) { current_tuple_length = QFILE_GET_TUPLE_LENGTH (current_tuple); for (col_index = 0; col_index < cursor_id_p->oid_col_no_cnt; col_index++) { col_num = cursor_id_p->oid_col_no[col_index]; type = cursor_id_p->list_id.type_list.domp[col_num]->type->id; tuple_p = (char *) current_tuple + QFILE_TUPLE_LENGTH_SIZE; for (j = col_num - 1; j >= 0; --j) { tuple_p += QFILE_TUPLE_VALUE_HEADER_SIZE + QFILE_GET_TUPLE_VALUE_LENGTH (tuple_p); } if (QFILE_GET_TUPLE_VALUE_FLAG (tuple_p) != V_BOUND) { continue; } if (type != DB_TYPE_OBJECT && type != DB_TYPE_VOBJ) { continue; } current_oid_p = cursor_get_oid_from_tuple (tuple_p, type); if (current_oid_p && oid_index < cursor_id_p->oid_ent_count) { /* for little endian */ if (type == DB_TYPE_VOBJ) { OR_PUT_OID (&cursor_id_p->oid_set[oid_index], current_oid_p); } else { COPY_OID (&cursor_id_p->oid_set[oid_index], current_oid_p); } oid_index++; } } current_tuple = (char *) current_tuple + current_tuple_length; } return cursor_fetch_oids (cursor_id_p, oid_index, DB_FETCH_READ, DB_FETCH_QUERY_READ); }
/* * boot_compact_db - compact specified classes * HEAP_CACHE_ATTRINFO structure * return: error status * class_oids(in): the classes list * n_classes(in): the class_oids length * hfids(in): the hfid list * space_to_process(in): the space to process * instance_lock_timeout(in): the lock timeout for instances * class_lock_timeout(in): the lock timeout for instances * delete_old_repr(in): whether to delete the old class representation * last_processed_class_oid(in,out): last processed class oid * last_processed_oid(in,out): last processed oid * total_objects(out): count processed objects for each class * failed_objects(out): count failed objects for each class * modified_objects(out): count modified objects for each class * big_objects(out): count big objects for each class * initial_last_repr_id(in, out): the list of initial last class * representation */ int boot_compact_db (THREAD_ENTRY * thread_p, OID * class_oids, int n_classes, int space_to_process, int instance_lock_timeout, int class_lock_timeout, bool delete_old_repr, OID * last_processed_class_oid, OID * last_processed_oid, int *total_objects, int *failed_objects, int *modified_objects, int *big_objects, int *initial_last_repr_id) { int result = NO_ERROR; int i, j, start_index = -1; int max_space_to_process, current_tran_index = -1; int lock_ret; HFID hfid; if (boot_can_compact (thread_p) == false) { return ER_COMPACTDB_ALREADY_STARTED; } if (class_oids == NULL || n_classes <= 0 || space_to_process <= 0 || last_processed_class_oid == NULL || last_processed_oid == NULL || total_objects == NULL || failed_objects == NULL || modified_objects == NULL || big_objects == NULL || initial_last_repr_id == NULL) { return ER_QPROC_INVALID_PARAMETER; } for (start_index = 0; start_index < n_classes; start_index++) { if (OID_EQ (class_oids + start_index, last_processed_class_oid)) { break; } } if (start_index == n_classes) { return ER_QPROC_INVALID_PARAMETER; } for (i = 0; i < n_classes; i++) { total_objects[i] = 0; failed_objects[i] = 0; modified_objects[i] = 0; big_objects[i] = 0; } max_space_to_process = space_to_process; for (i = start_index; i < n_classes; i++) { lock_ret = lock_object_waitsecs (thread_p, class_oids + i, oid_Root_class_oid, IX_LOCK, LK_UNCOND_LOCK, class_lock_timeout); if (lock_ret != LK_GRANTED) { total_objects[i] = COMPACTDB_LOCKED_CLASS; OID_SET_NULL (last_processed_oid); continue; } if (heap_get_hfid_from_class_oid (thread_p, class_oids + i, &hfid) != NO_ERROR) { lock_unlock_object (thread_p, class_oids + i, oid_Root_class_oid, IX_LOCK, true); OID_SET_NULL (last_processed_oid); total_objects[i] = COMPACTDB_INVALID_CLASS; continue; } if (HFID_IS_NULL (&hfid)) { lock_unlock_object (thread_p, class_oids + i, oid_Root_class_oid, IX_LOCK, true); OID_SET_NULL (last_processed_oid); total_objects[i] = COMPACTDB_INVALID_CLASS; continue; } if (OID_ISNULL (last_processed_oid)) { initial_last_repr_id[i] = heap_get_class_repr_id (thread_p, class_oids + i); if (initial_last_repr_id[i] <= 0) { lock_unlock_object (thread_p, class_oids + i, oid_Root_class_oid, IX_LOCK, true); total_objects[i] = COMPACTDB_INVALID_CLASS; continue; } } if (process_class (thread_p, class_oids + i, &hfid, max_space_to_process, &instance_lock_timeout, &space_to_process, last_processed_oid, total_objects + i, failed_objects + i, modified_objects + i, big_objects + i) != NO_ERROR) { OID_SET_NULL (last_processed_oid); for (j = start_index; j <= i; j++) { total_objects[j] = COMPACTDB_UNPROCESSED_CLASS; failed_objects[j] = 0; modified_objects[j] = 0; big_objects[j] = 0; } result = ER_FAILED; break; } if (delete_old_repr && OID_ISNULL (last_processed_oid) && failed_objects[i] == 0 && heap_get_class_repr_id (thread_p, class_oids + i) == initial_last_repr_id[i]) { lock_ret = lock_object_waitsecs (thread_p, class_oids + i, oid_Root_class_oid, X_LOCK, LK_UNCOND_LOCK, class_lock_timeout); if (lock_ret == LK_GRANTED) { if (catalog_drop_old_representations (thread_p, class_oids + i) != NO_ERROR) { for (j = start_index; j <= i; j++) { total_objects[j] = COMPACTDB_UNPROCESSED_CLASS; failed_objects[j] = 0; modified_objects[j] = 0; big_objects[j] = 0; } result = ER_FAILED; } else { initial_last_repr_id[i] = COMPACTDB_REPR_DELETED; } break; } } if (space_to_process == 0) { break; } } if (OID_ISNULL (last_processed_oid)) { if (i < n_classes - 1) { COPY_OID (last_processed_class_oid, class_oids + i + 1); } else { OID_SET_NULL (last_processed_class_oid); } } else { COPY_OID (last_processed_class_oid, class_oids + i); } return result; }
/* * process_class - process a class * HEAP_CACHE_ATTRINFO structure * return: error status * class_oid(in): the class OID * hfid(in): the class HFID * max_space_to_process(in): maximum space to process * instance_lock_timeout(in): the lock timeout for instances * space_to_process(in, out): space to process * last_processed_oid(in, out): last processed oid * total_objects(in, out): count the processed class objects * failed_objects(in, out): count the failed class objects * modified_objects(in, out): count the modified class objects * big_objects(in, out): count the big class objects */ static int process_class (THREAD_ENTRY * thread_p, OID * class_oid, HFID * hfid, int max_space_to_process, int *instance_lock_timeout, int *space_to_process, OID * last_processed_oid, int *total_objects, int *failed_objects, int *modified_objects, int *big_objects) { int nobjects, nfetched, i, j; OID last_oid, prev_oid; LOCK null_lock = NULL_LOCK; LOCK oid_lock = X_LOCK; LC_COPYAREA *fetch_area = NULL; /* Area where objects are received */ struct lc_copyarea_manyobjs *mobjs; /* Describe multiple objects in area */ struct lc_copyarea_oneobj *obj; /* Describe on object in area */ RECDES recdes; HEAP_CACHE_ATTRINFO attr_info; HEAP_SCANCACHE upd_scancache; int ret = NO_ERROR, object_processed; int nfailed_instances = 0; if (class_oid == NULL || hfid == NULL || space_to_process == NULL || *space_to_process <= 0 || *space_to_process > max_space_to_process || last_processed_oid == NULL || total_objects == NULL || failed_objects == NULL || modified_objects == NULL || big_objects == NULL || *total_objects < 0 || *failed_objects < 0) { return ER_FAILED; } nobjects = 0; nfetched = -1; ret = heap_scancache_start_modify (thread_p, &upd_scancache, hfid, class_oid, SINGLE_ROW_UPDATE); if (ret != NO_ERROR) { return ER_FAILED; } ret = heap_attrinfo_start (thread_p, class_oid, -1, NULL, &attr_info); if (ret != NO_ERROR) { heap_scancache_end_modify (thread_p, &upd_scancache); return ER_FAILED; } COPY_OID (&last_oid, last_processed_oid); COPY_OID (&prev_oid, last_processed_oid); while (nobjects != nfetched) { ret = xlocator_lock_and_fetch_all (thread_p, hfid, &oid_lock, instance_lock_timeout, class_oid, &null_lock, &nobjects, &nfetched, &nfailed_instances, &last_oid, &fetch_area); if (ret == NO_ERROR) { (*total_objects) += nfailed_instances; (*failed_objects) += nfailed_instances; if (fetch_area != NULL) { mobjs = LC_MANYOBJS_PTR_IN_COPYAREA (fetch_area); obj = LC_START_ONEOBJ_PTR_IN_COPYAREA (mobjs); for (i = 0; i < mobjs->num_objs; i++) { if (obj->length > *space_to_process) { if (*space_to_process == max_space_to_process) { (*total_objects)++; (*big_objects)++; lock_unlock_object (thread_p, &obj->oid, class_oid, oid_lock, true); } else { *space_to_process = 0; COPY_OID (last_processed_oid, &prev_oid); for (j = i; j < mobjs->num_objs; j++) { lock_unlock_object (thread_p, &obj->oid, class_oid, oid_lock, true); obj = LC_NEXT_ONEOBJ_PTR_IN_COPYAREA (obj); } if (fetch_area) { locator_free_copy_area (fetch_area); } goto end; } } else { *space_to_process -= obj->length; (*total_objects)++; LC_RECDES_TO_GET_ONEOBJ (fetch_area, obj, &recdes); if (desc_disk_to_attr_info (thread_p, &obj->oid, &recdes, &attr_info) == NO_ERROR) { object_processed = process_object (thread_p, &upd_scancache, &attr_info, &obj->oid); if (object_processed != 1) { lock_unlock_object (thread_p, &obj->oid, class_oid, oid_lock, true); if (object_processed == -1) { (*failed_objects)++; } } else { (*modified_objects)++; } } else { (*failed_objects)++; } } COPY_OID (&prev_oid, &obj->oid); obj = LC_NEXT_ONEOBJ_PTR_IN_COPYAREA (obj); } if (fetch_area) { locator_free_copy_area (fetch_area); } } else { /* No more objects */ break; } } else { ret = ER_FAILED; break; } } COPY_OID (last_processed_oid, &last_oid); end: heap_attrinfo_end (thread_p, &attr_info); heap_scancache_end_modify (thread_p, &upd_scancache); return ret; }
/* * disk_insert_instance_using_mobj - inserts a new object in the database * given a memory object and class object * return: NO_ERROR if successful, error code otherwise * classop(in): class object * classobj(in): class memory object * obj(in): object memory. * oid(out): oid of the destination */ int disk_insert_instance_using_mobj (MOP classop, MOBJ classobj, MOBJ obj, OID * oid) { int error = NO_ERROR; HFID *hfid; volatile int newsize = 0; bool has_indexes; TF_STATUS tf_status = TF_SUCCESS; Diskrec->length = 0; /* * tf_mem_to_disk() is used to get an estimate of the disk space requirements * for the object. When dealing with collections the estimate returned is * not always a good one, hence we need to enclose this block in a loop * increasing the space by increments of DB_PAGESIZE until we hit the correct * space requirement. */ while ((tf_status = tf_mem_to_disk (classop, classobj, obj, Diskrec, &has_indexes)) == TF_OUT_OF_SPACE) { /* make the record larger */ if (newsize) { newsize += DB_PAGESIZE; } else { newsize = -Diskrec->length + DB_PAGESIZE; } free_recdes (Diskrec); Diskrec = alloc_recdes (newsize); if (Diskrec == NULL) { assert (er_errid () != NO_ERROR); error = er_errid (); break; } } if (tf_status != TF_SUCCESS) { error = ER_LDR_CANT_TRANSFORM; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0); } if (error == NO_ERROR && Diskrec != NULL) { hfid = get_class_heap (classop, (SM_CLASS *) classop->object); if (hfid == NULL) { assert (er_errid () != NO_ERROR); error = er_errid (); } else { HEAP_OPERATION_CONTEXT context; /* set up context */ heap_create_insert_context (&context, hfid, WS_OID (classop), Diskrec, NULL); /* oid is set here as a side effect */ if (heap_insert_logical (NULL, &context) != NO_ERROR) { assert (er_errid () != NO_ERROR); error = er_errid (); } else if (has_indexes) { COPY_OID (oid, &context.res_oid); error = update_indexes (WS_OID (classop), oid, Diskrec); } else { COPY_OID (oid, &context.res_oid); } } } return (error); }