2005-10-27 07:29:40 +00:00
|
|
|
/******************************************************
|
|
|
|
Fresh insert undo
|
|
|
|
|
|
|
|
(c) 1996 Innobase Oy
|
|
|
|
|
|
|
|
Created 2/25/1997 Heikki Tuuri
|
|
|
|
*******************************************************/
|
|
|
|
|
|
|
|
#include "row0uins.h"
|
|
|
|
|
|
|
|
#ifdef UNIV_NONINL
|
|
|
|
#include "row0uins.ic"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "dict0dict.h"
|
|
|
|
#include "dict0boot.h"
|
|
|
|
#include "dict0crea.h"
|
|
|
|
#include "trx0undo.h"
|
|
|
|
#include "trx0roll.h"
|
|
|
|
#include "btr0btr.h"
|
|
|
|
#include "mach0data.h"
|
|
|
|
#include "row0undo.h"
|
|
|
|
#include "row0vers.h"
|
|
|
|
#include "trx0trx.h"
|
|
|
|
#include "trx0rec.h"
|
|
|
|
#include "row0row.h"
|
|
|
|
#include "row0upd.h"
|
|
|
|
#include "que0que.h"
|
|
|
|
#include "ibuf0ibuf.h"
|
|
|
|
#include "log0log.h"
|
|
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
Removes a clustered index record. The pcur in node was positioned on the
|
|
|
|
record, now it is detached. */
|
|
|
|
static
|
|
|
|
ulint
|
|
|
|
row_undo_ins_remove_clust_rec(
|
|
|
|
/*==========================*/
|
|
|
|
/* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
|
|
|
|
undo_node_t* node) /* in: undo node */
|
|
|
|
{
|
2006-02-23 19:25:29 +00:00
|
|
|
btr_cur_t* btr_cur;
|
2005-10-27 07:29:40 +00:00
|
|
|
ibool success;
|
|
|
|
ulint err;
|
|
|
|
ulint n_tries = 0;
|
|
|
|
mtr_t mtr;
|
2006-02-23 19:25:29 +00:00
|
|
|
|
2005-10-27 07:29:40 +00:00
|
|
|
mtr_start(&mtr);
|
2006-02-23 19:25:29 +00:00
|
|
|
|
2005-10-27 07:29:40 +00:00
|
|
|
success = btr_pcur_restore_position(BTR_MODIFY_LEAF, &(node->pcur),
|
2006-08-29 09:30:31 +00:00
|
|
|
&mtr);
|
2005-10-27 07:29:40 +00:00
|
|
|
ut_a(success);
|
|
|
|
|
|
|
|
if (ut_dulint_cmp(node->table->id, DICT_INDEXES_ID) == 0) {
|
2007-08-29 06:36:10 +00:00
|
|
|
ut_ad(node->trx->dict_operation_lock_mode == RW_X_LATCH);
|
2005-10-27 07:29:40 +00:00
|
|
|
|
|
|
|
/* Drop the index tree associated with the row in
|
|
|
|
SYS_INDEXES table: */
|
2006-02-23 19:25:29 +00:00
|
|
|
|
2005-10-27 07:29:40 +00:00
|
|
|
dict_drop_index_tree(btr_pcur_get_rec(&(node->pcur)), &mtr);
|
|
|
|
|
|
|
|
mtr_commit(&mtr);
|
|
|
|
|
|
|
|
mtr_start(&mtr);
|
|
|
|
|
|
|
|
success = btr_pcur_restore_position(BTR_MODIFY_LEAF,
|
2006-08-29 09:30:31 +00:00
|
|
|
&(node->pcur), &mtr);
|
2005-10-27 07:29:40 +00:00
|
|
|
ut_a(success);
|
|
|
|
}
|
2006-02-23 19:25:29 +00:00
|
|
|
|
2005-10-27 07:29:40 +00:00
|
|
|
btr_cur = btr_pcur_get_btr_cur(&(node->pcur));
|
2006-02-23 19:25:29 +00:00
|
|
|
|
2005-10-27 07:29:40 +00:00
|
|
|
success = btr_cur_optimistic_delete(btr_cur, &mtr);
|
|
|
|
|
|
|
|
btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
trx_undo_rec_release(node->trx, node->undo_no);
|
|
|
|
|
|
|
|
return(DB_SUCCESS);
|
|
|
|
}
|
|
|
|
retry:
|
|
|
|
/* If did not succeed, try pessimistic descent to tree */
|
|
|
|
mtr_start(&mtr);
|
2006-02-23 19:25:29 +00:00
|
|
|
|
2005-10-27 07:29:40 +00:00
|
|
|
success = btr_pcur_restore_position(BTR_MODIFY_TREE,
|
2006-08-29 09:30:31 +00:00
|
|
|
&(node->pcur), &mtr);
|
2005-10-27 07:29:40 +00:00
|
|
|
ut_a(success);
|
|
|
|
|
branches/zip: In the rollback of incomplete transactions after crash
recovery, tolerate clustered index records whose externally stored
columns have not been written. This should remove the assertion failures
that were reported as Mantis issue#58, issue#62, issue#64.
trx_is_recv(): New function: TRUE if this transaction is rolling back
an incomplete transaction in crash recovery.
enum trx_rbmode: Rollback modes: no rollback, normal rollback, crash recovery.
btr_cur_pessimistic_delete(), btr_free_externally_stored_field(),
btr_rec_free_externally_stored_fields():
Replace the ibool parameter with enum trx_rbmode.
btr_free_externally_stored_field(): If field_ref is zero, return
but assert ut_a(rbmode == RB_RECOVERY). Unless InnoDB has crashed
while inserting a clustered index record, field_ref should not be zero.
btr_rec_free_updated_extern_fields(): Add the parameter enum trx_rbmode.
btr_cur_pessimistic_update(): Pass the rbmode parameter to
btr_rec_free_updated_extern_fields().
row_undo_ins(), row_undo_mod_upd_del_sec(): If row_build_index_entry()
fails, assert trx_is_recv() and skip this secondary index.
row_undo_mod_upd_del_sec(): Empty the heap at the end of each loop
iteration in order to conserve memory and to reduce the number of
low-level memory allocations.
2008-08-06 08:48:34 +00:00
|
|
|
btr_cur_pessimistic_delete(&err, FALSE, btr_cur,
|
|
|
|
trx_is_recv(node->trx)
|
|
|
|
? RB_RECOVERY
|
|
|
|
: RB_NORMAL, &mtr);
|
2005-10-27 07:29:40 +00:00
|
|
|
|
|
|
|
/* The delete operation may fail if we have little
|
|
|
|
file space left: TODO: easiest to crash the database
|
|
|
|
and restart with more file space */
|
|
|
|
|
|
|
|
if (err == DB_OUT_OF_FILE_SPACE
|
2006-08-29 09:30:31 +00:00
|
|
|
&& n_tries < BTR_CUR_RETRY_DELETE_N_TIMES) {
|
2005-10-27 07:29:40 +00:00
|
|
|
|
|
|
|
btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
|
|
|
|
|
|
|
|
n_tries++;
|
|
|
|
|
|
|
|
os_thread_sleep(BTR_CUR_RETRY_SLEEP_TIME);
|
2006-02-23 19:25:29 +00:00
|
|
|
|
2005-10-27 07:29:40 +00:00
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
|
|
|
|
btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
|
|
|
|
|
|
|
|
trx_undo_rec_release(node->trx, node->undo_no);
|
|
|
|
|
|
|
|
return(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
Removes a secondary index entry if found. */
|
|
|
|
static
|
|
|
|
ulint
|
|
|
|
row_undo_ins_remove_sec_low(
|
|
|
|
/*========================*/
|
|
|
|
/* out: DB_SUCCESS, DB_FAIL, or
|
|
|
|
DB_OUT_OF_FILE_SPACE */
|
|
|
|
ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
|
|
|
|
depending on whether we wish optimistic or
|
|
|
|
pessimistic descent down the index tree */
|
|
|
|
dict_index_t* index, /* in: index */
|
|
|
|
dtuple_t* entry) /* in: index entry to remove */
|
|
|
|
{
|
2006-02-23 19:25:29 +00:00
|
|
|
btr_pcur_t pcur;
|
2005-10-27 07:29:40 +00:00
|
|
|
btr_cur_t* btr_cur;
|
|
|
|
ibool found;
|
|
|
|
ibool success;
|
|
|
|
ulint err;
|
|
|
|
mtr_t mtr;
|
2006-02-23 19:25:29 +00:00
|
|
|
|
2005-10-27 07:29:40 +00:00
|
|
|
log_free_check();
|
|
|
|
mtr_start(&mtr);
|
|
|
|
|
|
|
|
found = row_search_index_entry(index, entry, mode, &pcur, &mtr);
|
|
|
|
|
|
|
|
btr_cur = btr_pcur_get_btr_cur(&pcur);
|
|
|
|
|
|
|
|
if (!found) {
|
|
|
|
/* Not found */
|
|
|
|
|
|
|
|
btr_pcur_close(&pcur);
|
|
|
|
mtr_commit(&mtr);
|
|
|
|
|
|
|
|
return(DB_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode == BTR_MODIFY_LEAF) {
|
|
|
|
success = btr_cur_optimistic_delete(btr_cur, &mtr);
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
err = DB_SUCCESS;
|
|
|
|
} else {
|
|
|
|
err = DB_FAIL;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ut_ad(mode == BTR_MODIFY_TREE);
|
|
|
|
|
branches/zip: In the rollback of incomplete transactions after crash
recovery, tolerate clustered index records whose externally stored
columns have not been written. This should remove the assertion failures
that were reported as Mantis issue#58, issue#62, issue#64.
trx_is_recv(): New function: TRUE if this transaction is rolling back
an incomplete transaction in crash recovery.
enum trx_rbmode: Rollback modes: no rollback, normal rollback, crash recovery.
btr_cur_pessimistic_delete(), btr_free_externally_stored_field(),
btr_rec_free_externally_stored_fields():
Replace the ibool parameter with enum trx_rbmode.
btr_free_externally_stored_field(): If field_ref is zero, return
but assert ut_a(rbmode == RB_RECOVERY). Unless InnoDB has crashed
while inserting a clustered index record, field_ref should not be zero.
btr_rec_free_updated_extern_fields(): Add the parameter enum trx_rbmode.
btr_cur_pessimistic_update(): Pass the rbmode parameter to
btr_rec_free_updated_extern_fields().
row_undo_ins(), row_undo_mod_upd_del_sec(): If row_build_index_entry()
fails, assert trx_is_recv() and skip this secondary index.
row_undo_mod_upd_del_sec(): Empty the heap at the end of each loop
iteration in order to conserve memory and to reduce the number of
low-level memory allocations.
2008-08-06 08:48:34 +00:00
|
|
|
/* No need to distinguish RB_RECOVERY here, because we
|
|
|
|
are deleting a secondary index record: the distinction
|
|
|
|
between RB_NORMAL and RB_RECOVERY only matters when
|
|
|
|
deleting a record that contains externally stored
|
|
|
|
columns. */
|
|
|
|
ut_ad(!dict_index_is_clust(index));
|
|
|
|
btr_cur_pessimistic_delete(&err, FALSE, btr_cur,
|
|
|
|
RB_NORMAL, &mtr);
|
2005-10-27 07:29:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
btr_pcur_close(&pcur);
|
|
|
|
mtr_commit(&mtr);
|
|
|
|
|
|
|
|
return(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
Removes a secondary index entry from the index if found. Tries first
|
|
|
|
optimistic, then pessimistic descent down the tree. */
|
|
|
|
static
|
|
|
|
ulint
|
|
|
|
row_undo_ins_remove_sec(
|
|
|
|
/*====================*/
|
|
|
|
/* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
|
|
|
|
dict_index_t* index, /* in: index */
|
|
|
|
dtuple_t* entry) /* in: index entry to insert */
|
|
|
|
{
|
|
|
|
ulint err;
|
|
|
|
ulint n_tries = 0;
|
2006-02-23 19:25:29 +00:00
|
|
|
|
2005-10-27 07:29:40 +00:00
|
|
|
/* Try first optimistic descent to the B-tree */
|
|
|
|
|
|
|
|
err = row_undo_ins_remove_sec_low(BTR_MODIFY_LEAF, index, entry);
|
2006-02-23 19:25:29 +00:00
|
|
|
|
2005-10-27 07:29:40 +00:00
|
|
|
if (err == DB_SUCCESS) {
|
|
|
|
|
|
|
|
return(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Try then pessimistic descent to the B-tree */
|
|
|
|
retry:
|
|
|
|
err = row_undo_ins_remove_sec_low(BTR_MODIFY_TREE, index, entry);
|
|
|
|
|
|
|
|
/* The delete operation may fail if we have little
|
|
|
|
file space left: TODO: easiest to crash the database
|
|
|
|
and restart with more file space */
|
|
|
|
|
|
|
|
if (err != DB_SUCCESS && n_tries < BTR_CUR_RETRY_DELETE_N_TIMES) {
|
|
|
|
|
|
|
|
n_tries++;
|
|
|
|
|
|
|
|
os_thread_sleep(BTR_CUR_RETRY_SLEEP_TIME);
|
2006-02-23 19:25:29 +00:00
|
|
|
|
2005-10-27 07:29:40 +00:00
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
|
|
|
|
return(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************
|
|
|
|
Parses the row reference and other info in a fresh insert undo record. */
|
|
|
|
static
|
|
|
|
void
|
|
|
|
row_undo_ins_parse_undo_rec(
|
|
|
|
/*========================*/
|
2008-10-16 15:57:58 +00:00
|
|
|
undo_node_t* node) /* in/out: row undo node */
|
2005-10-27 07:29:40 +00:00
|
|
|
{
|
2007-09-05 10:18:03 +00:00
|
|
|
dict_index_t* clust_index;
|
2005-10-27 07:29:40 +00:00
|
|
|
byte* ptr;
|
2007-09-05 10:18:03 +00:00
|
|
|
dulint undo_no;
|
2005-10-27 07:29:40 +00:00
|
|
|
dulint table_id;
|
2007-09-05 10:18:03 +00:00
|
|
|
ulint type;
|
|
|
|
ulint dummy;
|
|
|
|
ibool dummy_extern;
|
2005-10-27 07:29:40 +00:00
|
|
|
|
|
|
|
ut_ad(node);
|
2006-02-23 19:25:29 +00:00
|
|
|
|
2007-09-05 10:18:03 +00:00
|
|
|
ptr = trx_undo_rec_get_pars(node->undo_rec, &type, &dummy,
|
|
|
|
&dummy_extern, &undo_no, &table_id);
|
|
|
|
ut_ad(type == TRX_UNDO_INSERT_REC);
|
|
|
|
node->rec_type = type;
|
2005-10-27 07:29:40 +00:00
|
|
|
|
2008-01-16 09:45:22 +00:00
|
|
|
node->update = NULL;
|
2007-09-05 10:18:03 +00:00
|
|
|
node->table = dict_table_get_on_id(table_id, node->trx);
|
2006-02-23 19:25:29 +00:00
|
|
|
|
2007-09-05 10:18:03 +00:00
|
|
|
/* Skip the UNDO if we can't find the table or the .ibd file. */
|
|
|
|
if (UNIV_UNLIKELY(node->table == NULL)) {
|
|
|
|
} else if (UNIV_UNLIKELY(node->table->ibd_file_missing)) {
|
|
|
|
node->table = NULL;
|
|
|
|
} else {
|
|
|
|
clust_index = dict_table_get_first_index(node->table);
|
2007-04-04 11:05:33 +00:00
|
|
|
|
2008-10-16 15:57:58 +00:00
|
|
|
if (clust_index != NULL) {
|
|
|
|
ptr = trx_undo_rec_get_row_ref(
|
|
|
|
ptr, clust_index, &node->ref, node->heap);
|
|
|
|
} else {
|
|
|
|
ut_print_timestamp(stderr);
|
2008-10-20 09:41:04 +00:00
|
|
|
fprintf(stderr, " InnoDB: table ");
|
|
|
|
ut_print_name(stderr, node->trx, TRUE,
|
|
|
|
node->table->name);
|
|
|
|
fprintf(stderr, " has no indexes, "
|
|
|
|
"ignoring the table\n");
|
|
|
|
|
2008-10-16 15:57:58 +00:00
|
|
|
node->table = NULL;
|
|
|
|
}
|
2007-04-04 11:05:33 +00:00
|
|
|
}
|
2005-10-27 07:29:40 +00:00
|
|
|
}
|
2006-02-23 19:25:29 +00:00
|
|
|
|
2005-10-27 07:29:40 +00:00
|
|
|
/***************************************************************
|
|
|
|
Undoes a fresh insert of a row to a table. A fresh insert means that
|
|
|
|
the same clustered index unique key did not have any record, even delete
|
|
|
|
marked, at the time of the insert. */
|
2008-02-06 14:17:36 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
ulint
|
|
|
|
row_undo_ins(
|
|
|
|
/*=========*/
|
|
|
|
/* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
|
|
|
|
undo_node_t* node) /* in: row undo node */
|
|
|
|
{
|
|
|
|
ut_ad(node);
|
|
|
|
ut_ad(node->state == UNDO_NODE_INSERT);
|
2006-02-23 19:25:29 +00:00
|
|
|
|
2005-10-27 07:29:40 +00:00
|
|
|
row_undo_ins_parse_undo_rec(node);
|
|
|
|
|
2007-05-18 10:53:29 +00:00
|
|
|
if (!node->table || !row_undo_search_clust_to_pcur(node)) {
|
2006-02-23 19:25:29 +00:00
|
|
|
trx_undo_rec_release(node->trx, node->undo_no);
|
2005-10-27 07:29:40 +00:00
|
|
|
|
2007-05-18 10:53:29 +00:00
|
|
|
return(DB_SUCCESS);
|
|
|
|
}
|
2005-10-27 07:29:40 +00:00
|
|
|
|
2007-05-18 10:53:29 +00:00
|
|
|
/* Iterate over all the indexes and undo the insert.*/
|
2005-10-27 07:29:40 +00:00
|
|
|
|
2007-05-18 10:53:29 +00:00
|
|
|
/* Skip the clustered index (the first index) */
|
|
|
|
node->index = dict_table_get_next_index(
|
|
|
|
dict_table_get_first_index(node->table));
|
2005-10-27 07:29:40 +00:00
|
|
|
|
2007-05-18 10:53:29 +00:00
|
|
|
while (node->index != NULL) {
|
|
|
|
dtuple_t* entry;
|
|
|
|
ulint err;
|
2005-10-27 07:29:40 +00:00
|
|
|
|
2007-05-18 10:53:29 +00:00
|
|
|
entry = row_build_index_entry(node->row, node->ext,
|
|
|
|
node->index, node->heap);
|
branches/zip: In the rollback of incomplete transactions after crash
recovery, tolerate clustered index records whose externally stored
columns have not been written. This should remove the assertion failures
that were reported as Mantis issue#58, issue#62, issue#64.
trx_is_recv(): New function: TRUE if this transaction is rolling back
an incomplete transaction in crash recovery.
enum trx_rbmode: Rollback modes: no rollback, normal rollback, crash recovery.
btr_cur_pessimistic_delete(), btr_free_externally_stored_field(),
btr_rec_free_externally_stored_fields():
Replace the ibool parameter with enum trx_rbmode.
btr_free_externally_stored_field(): If field_ref is zero, return
but assert ut_a(rbmode == RB_RECOVERY). Unless InnoDB has crashed
while inserting a clustered index record, field_ref should not be zero.
btr_rec_free_updated_extern_fields(): Add the parameter enum trx_rbmode.
btr_cur_pessimistic_update(): Pass the rbmode parameter to
btr_rec_free_updated_extern_fields().
row_undo_ins(), row_undo_mod_upd_del_sec(): If row_build_index_entry()
fails, assert trx_is_recv() and skip this secondary index.
row_undo_mod_upd_del_sec(): Empty the heap at the end of each loop
iteration in order to conserve memory and to reduce the number of
low-level memory allocations.
2008-08-06 08:48:34 +00:00
|
|
|
if (UNIV_UNLIKELY(!entry)) {
|
|
|
|
/* The database must have crashed after
|
|
|
|
inserting a clustered index record but before
|
|
|
|
writing all the externally stored columns of
|
|
|
|
that record. Because secondary index entries
|
|
|
|
are inserted after the clustered index record,
|
|
|
|
we may assume that the secondary index record
|
|
|
|
does not exist. However, this situation may
|
|
|
|
only occur during the rollback of incomplete
|
|
|
|
transactions. */
|
|
|
|
ut_a(trx_is_recv(node->trx));
|
|
|
|
} else {
|
|
|
|
err = row_undo_ins_remove_sec(node->index, entry);
|
2007-04-04 11:05:33 +00:00
|
|
|
|
branches/zip: In the rollback of incomplete transactions after crash
recovery, tolerate clustered index records whose externally stored
columns have not been written. This should remove the assertion failures
that were reported as Mantis issue#58, issue#62, issue#64.
trx_is_recv(): New function: TRUE if this transaction is rolling back
an incomplete transaction in crash recovery.
enum trx_rbmode: Rollback modes: no rollback, normal rollback, crash recovery.
btr_cur_pessimistic_delete(), btr_free_externally_stored_field(),
btr_rec_free_externally_stored_fields():
Replace the ibool parameter with enum trx_rbmode.
btr_free_externally_stored_field(): If field_ref is zero, return
but assert ut_a(rbmode == RB_RECOVERY). Unless InnoDB has crashed
while inserting a clustered index record, field_ref should not be zero.
btr_rec_free_updated_extern_fields(): Add the parameter enum trx_rbmode.
btr_cur_pessimistic_update(): Pass the rbmode parameter to
btr_rec_free_updated_extern_fields().
row_undo_ins(), row_undo_mod_upd_del_sec(): If row_build_index_entry()
fails, assert trx_is_recv() and skip this secondary index.
row_undo_mod_upd_del_sec(): Empty the heap at the end of each loop
iteration in order to conserve memory and to reduce the number of
low-level memory allocations.
2008-08-06 08:48:34 +00:00
|
|
|
if (err != DB_SUCCESS) {
|
2007-04-04 11:05:33 +00:00
|
|
|
|
branches/zip: In the rollback of incomplete transactions after crash
recovery, tolerate clustered index records whose externally stored
columns have not been written. This should remove the assertion failures
that were reported as Mantis issue#58, issue#62, issue#64.
trx_is_recv(): New function: TRUE if this transaction is rolling back
an incomplete transaction in crash recovery.
enum trx_rbmode: Rollback modes: no rollback, normal rollback, crash recovery.
btr_cur_pessimistic_delete(), btr_free_externally_stored_field(),
btr_rec_free_externally_stored_fields():
Replace the ibool parameter with enum trx_rbmode.
btr_free_externally_stored_field(): If field_ref is zero, return
but assert ut_a(rbmode == RB_RECOVERY). Unless InnoDB has crashed
while inserting a clustered index record, field_ref should not be zero.
btr_rec_free_updated_extern_fields(): Add the parameter enum trx_rbmode.
btr_cur_pessimistic_update(): Pass the rbmode parameter to
btr_rec_free_updated_extern_fields().
row_undo_ins(), row_undo_mod_upd_del_sec(): If row_build_index_entry()
fails, assert trx_is_recv() and skip this secondary index.
row_undo_mod_upd_del_sec(): Empty the heap at the end of each loop
iteration in order to conserve memory and to reduce the number of
low-level memory allocations.
2008-08-06 08:48:34 +00:00
|
|
|
return(err);
|
|
|
|
}
|
2005-10-27 07:29:40 +00:00
|
|
|
}
|
2006-02-23 19:25:29 +00:00
|
|
|
|
2007-05-18 10:53:29 +00:00
|
|
|
node->index = dict_table_get_next_index(node->index);
|
2005-10-27 07:29:40 +00:00
|
|
|
}
|
|
|
|
|
2007-05-18 10:53:29 +00:00
|
|
|
return(row_undo_ins_remove_clust_rec(node));
|
2005-10-27 07:29:40 +00:00
|
|
|
}
|