2001-02-17 13:19:19 +01:00
|
|
|
/******************************************************
|
|
|
|
Interface between Innobase row operations and MySQL.
|
|
|
|
Contains also create table and other data dictionary operations.
|
|
|
|
|
|
|
|
(c) 2000 Innobase Oy
|
|
|
|
|
|
|
|
Created 9/17/2000 Heikki Tuuri
|
|
|
|
*******************************************************/
|
|
|
|
|
|
|
|
#include "row0mysql.h"
|
|
|
|
|
|
|
|
#ifdef UNIV_NONINL
|
|
|
|
#include "row0mysql.ic"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "row0ins.h"
|
|
|
|
#include "row0sel.h"
|
|
|
|
#include "row0upd.h"
|
|
|
|
#include "row0row.h"
|
|
|
|
#include "que0que.h"
|
|
|
|
#include "pars0pars.h"
|
|
|
|
#include "dict0dict.h"
|
|
|
|
#include "dict0crea.h"
|
|
|
|
#include "trx0roll.h"
|
|
|
|
#include "trx0purge.h"
|
|
|
|
#include "lock0lock.h"
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
Reads a MySQL format variable-length field (like VARCHAR) length and
|
|
|
|
returns pointer to the field data. */
|
|
|
|
|
|
|
|
byte*
|
|
|
|
row_mysql_read_var_ref_noninline(
|
|
|
|
/*=============================*/
|
|
|
|
/* out: field + 2 */
|
|
|
|
ulint* len, /* out: variable-length field length */
|
|
|
|
byte* field) /* in: field */
|
|
|
|
{
|
|
|
|
return(row_mysql_read_var_ref(len, field));
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
Stores a reference to a BLOB in the MySQL format. */
|
|
|
|
|
|
|
|
void
|
|
|
|
row_mysql_store_blob_ref(
|
|
|
|
/*=====================*/
|
|
|
|
byte* dest, /* in: where to store */
|
|
|
|
ulint col_len, /* in: dest buffer size: determines into
|
|
|
|
how many bytes the BLOB length is stored,
|
|
|
|
this may vary from 1 to 4 bytes */
|
|
|
|
byte* data, /* in: BLOB data */
|
|
|
|
ulint len) /* in: BLOB length */
|
|
|
|
{
|
|
|
|
/* In dest there are 1 - 4 bytes reserved for the BLOB length,
|
|
|
|
and after that 8 bytes reserved for the pointer to the data.
|
|
|
|
In 32-bit architectures we only use the first 4 bytes of the pointer
|
|
|
|
slot. */
|
|
|
|
|
|
|
|
mach_write_to_n_little_endian(dest, col_len - 8, len);
|
|
|
|
|
|
|
|
ut_memcpy(dest + col_len - 8, (byte*)&data, sizeof(byte*));
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
Reads a reference to a BLOB in the MySQL format. */
|
|
|
|
|
|
|
|
byte*
|
|
|
|
row_mysql_read_blob_ref(
|
|
|
|
/*====================*/
|
|
|
|
/* out: pointer to BLOB data */
|
|
|
|
ulint* len, /* out: BLOB length */
|
|
|
|
byte* ref, /* in: BLOB reference in the MySQL format */
|
|
|
|
ulint col_len) /* in: BLOB reference length (not BLOB
|
|
|
|
length) */
|
|
|
|
{
|
|
|
|
byte* data;
|
|
|
|
|
|
|
|
*len = mach_read_from_n_little_endian(ref, col_len - 8);
|
|
|
|
|
|
|
|
ut_memcpy((byte*)&data, ref + col_len - 8, sizeof(byte*));
|
|
|
|
|
|
|
|
return(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************
|
|
|
|
Convert a row in the MySQL format to a row in the Innobase format. */
|
|
|
|
static
|
|
|
|
void
|
|
|
|
row_mysql_convert_row_to_innobase(
|
|
|
|
/*==============================*/
|
|
|
|
dtuple_t* row, /* in/out: Innobase row where the
|
|
|
|
field type information is already
|
|
|
|
copied there, or will be copied
|
|
|
|
later */
|
|
|
|
row_prebuilt_t* prebuilt, /* in: prebuilt struct where template
|
|
|
|
must be of type ROW_MYSQL_WHOLE_ROW */
|
|
|
|
byte* mysql_rec) /* in: row in the MySQL format;
|
|
|
|
NOTE: do not discard as long as
|
|
|
|
row is used, as row may contain
|
|
|
|
pointers to this record! */
|
|
|
|
{
|
|
|
|
mysql_row_templ_t* templ;
|
|
|
|
dfield_t* dfield;
|
|
|
|
ulint i;
|
|
|
|
|
|
|
|
ut_ad(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
|
|
|
|
ut_ad(prebuilt->mysql_template);
|
|
|
|
|
|
|
|
for (i = 0; i < prebuilt->n_template; i++) {
|
|
|
|
|
|
|
|
templ = prebuilt->mysql_template + i;
|
|
|
|
dfield = dtuple_get_nth_field(row, i);
|
|
|
|
|
|
|
|
if (templ->mysql_null_bit_mask != 0) {
|
|
|
|
/* Column may be SQL NULL */
|
|
|
|
|
|
|
|
if (mysql_rec[templ->mysql_null_byte_offset] &
|
|
|
|
(byte) (templ->mysql_null_bit_mask)) {
|
|
|
|
|
|
|
|
/* It is SQL NULL */
|
|
|
|
|
|
|
|
dfield_set_data(dfield, NULL, UNIV_SQL_NULL);
|
|
|
|
|
|
|
|
goto next_column;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
row_mysql_store_col_in_innobase_format(dfield,
|
|
|
|
prebuilt->ins_upd_rec_buff
|
|
|
|
+ templ->mysql_col_offset,
|
|
|
|
mysql_rec + templ->mysql_col_offset,
|
|
|
|
templ->mysql_col_len,
|
|
|
|
templ->type, templ->is_unsigned);
|
|
|
|
next_column:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
Handles user errors and lock waits detected by the database engine. */
|
|
|
|
|
|
|
|
ibool
|
|
|
|
row_mysql_handle_errors(
|
|
|
|
/*====================*/
|
|
|
|
/* out: TRUE if it was a lock wait and
|
|
|
|
we should continue running the query thread */
|
|
|
|
ulint* new_err,/* out: possible new error encountered in
|
|
|
|
rollback, or the old error which was
|
|
|
|
during the function entry */
|
|
|
|
trx_t* trx, /* in: transaction */
|
|
|
|
que_thr_t* thr, /* in: query thread */
|
|
|
|
trx_savept_t* savept) /* in: savepoint */
|
|
|
|
{
|
|
|
|
ibool timeout_expired;
|
|
|
|
ulint err;
|
|
|
|
|
|
|
|
handle_new_error:
|
|
|
|
err = trx->error_state;
|
|
|
|
|
|
|
|
ut_a(err != DB_SUCCESS);
|
|
|
|
|
|
|
|
trx->error_state = DB_SUCCESS;
|
|
|
|
|
|
|
|
if (err == DB_DUPLICATE_KEY) {
|
|
|
|
if (savept) {
|
|
|
|
/* Roll back the latest, possibly incomplete
|
|
|
|
insertion or update */
|
|
|
|
|
|
|
|
trx_general_rollback_for_mysql(trx, TRUE, savept);
|
|
|
|
}
|
|
|
|
} else if (err == DB_TOO_BIG_RECORD) {
|
|
|
|
if (savept) {
|
|
|
|
/* Roll back the latest, possibly incomplete
|
|
|
|
insertion or update */
|
|
|
|
|
|
|
|
trx_general_rollback_for_mysql(trx, TRUE, savept);
|
|
|
|
}
|
|
|
|
} else if (err == DB_LOCK_WAIT) {
|
|
|
|
|
|
|
|
timeout_expired = srv_suspend_mysql_thread(thr);
|
|
|
|
|
|
|
|
if (timeout_expired) {
|
|
|
|
trx->error_state = DB_DEADLOCK;
|
|
|
|
|
|
|
|
que_thr_stop_for_mysql(thr);
|
|
|
|
|
|
|
|
goto handle_new_error;
|
|
|
|
}
|
|
|
|
|
|
|
|
*new_err = err;
|
|
|
|
|
|
|
|
return(TRUE);
|
|
|
|
|
|
|
|
} else if (err == DB_DEADLOCK) {
|
|
|
|
|
|
|
|
/* Roll back the whole transaction */
|
|
|
|
|
|
|
|
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
|
|
|
|
|
|
|
} else if (err == DB_OUT_OF_FILE_SPACE) {
|
|
|
|
|
|
|
|
/* Roll back the whole transaction */
|
|
|
|
|
|
|
|
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
|
|
|
} else if (err == DB_MUST_GET_MORE_FILE_SPACE) {
|
|
|
|
|
|
|
|
ut_a(0); /* TODO: print something to MySQL error log */
|
|
|
|
} else {
|
|
|
|
ut_a(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (trx->error_state != DB_SUCCESS) {
|
|
|
|
*new_err = trx->error_state;
|
|
|
|
} else {
|
|
|
|
*new_err = err;
|
|
|
|
}
|
|
|
|
|
|
|
|
trx->error_state = DB_SUCCESS;
|
|
|
|
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Create a prebuilt struct for a MySQL table handle. */
|
|
|
|
|
|
|
|
row_prebuilt_t*
|
|
|
|
row_create_prebuilt(
|
|
|
|
/*================*/
|
|
|
|
/* out, own: a prebuilt struct */
|
|
|
|
dict_table_t* table) /* in: Innobase table handle */
|
|
|
|
{
|
|
|
|
row_prebuilt_t* prebuilt;
|
|
|
|
mem_heap_t* heap;
|
|
|
|
dict_index_t* clust_index;
|
|
|
|
dtuple_t* ref;
|
|
|
|
ulint ref_len;
|
|
|
|
ulint i;
|
|
|
|
|
|
|
|
heap = mem_heap_create(128);
|
|
|
|
|
|
|
|
prebuilt = mem_heap_alloc(heap, sizeof(row_prebuilt_t));
|
|
|
|
|
|
|
|
prebuilt->table = table;
|
|
|
|
|
|
|
|
prebuilt->trx = NULL;
|
|
|
|
|
|
|
|
prebuilt->sql_stat_start = TRUE;
|
|
|
|
|
|
|
|
prebuilt->index = NULL;
|
|
|
|
prebuilt->n_template = 0;
|
|
|
|
prebuilt->mysql_template = NULL;
|
|
|
|
|
|
|
|
prebuilt->heap = heap;
|
|
|
|
prebuilt->ins_node = NULL;
|
|
|
|
|
|
|
|
prebuilt->ins_upd_rec_buff = NULL;
|
|
|
|
|
|
|
|
prebuilt->upd_node = NULL;
|
|
|
|
prebuilt->ins_graph = NULL;
|
|
|
|
prebuilt->upd_graph = NULL;
|
|
|
|
|
|
|
|
prebuilt->pcur = btr_pcur_create_for_mysql();
|
|
|
|
prebuilt->clust_pcur = btr_pcur_create_for_mysql();
|
|
|
|
|
|
|
|
prebuilt->select_lock_type = LOCK_NONE;
|
|
|
|
|
|
|
|
prebuilt->sel_graph = NULL;
|
|
|
|
|
|
|
|
prebuilt->search_tuple = dtuple_create(heap,
|
|
|
|
dict_table_get_n_cols(table));
|
|
|
|
|
|
|
|
clust_index = dict_table_get_first_index(table);
|
|
|
|
|
|
|
|
ref_len = dict_index_get_n_unique(clust_index);
|
|
|
|
|
|
|
|
ref = dtuple_create(heap, ref_len);
|
|
|
|
|
|
|
|
dict_index_copy_types(ref, clust_index, ref_len);
|
|
|
|
|
|
|
|
prebuilt->clust_ref = ref;
|
|
|
|
|
|
|
|
for (i = 0; i < MYSQL_FETCH_CACHE_SIZE; i++) {
|
|
|
|
prebuilt->fetch_cache[i] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
prebuilt->n_fetch_cached = 0;
|
|
|
|
|
|
|
|
prebuilt->blob_heap = NULL;
|
|
|
|
|
|
|
|
prebuilt->old_vers_heap = NULL;
|
|
|
|
|
|
|
|
return(prebuilt);
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Free a prebuilt struct for a MySQL table handle. */
|
|
|
|
|
|
|
|
void
|
|
|
|
row_prebuilt_free(
|
|
|
|
/*==============*/
|
|
|
|
row_prebuilt_t* prebuilt) /* in, own: prebuilt struct */
|
|
|
|
{
|
|
|
|
ulint i;
|
|
|
|
|
|
|
|
btr_pcur_free_for_mysql(prebuilt->pcur);
|
|
|
|
btr_pcur_free_for_mysql(prebuilt->clust_pcur);
|
|
|
|
|
|
|
|
if (prebuilt->mysql_template) {
|
|
|
|
mem_free(prebuilt->mysql_template);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (prebuilt->ins_graph) {
|
|
|
|
que_graph_free_recursive(prebuilt->ins_graph);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (prebuilt->sel_graph) {
|
|
|
|
que_graph_free_recursive(prebuilt->sel_graph);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (prebuilt->upd_graph) {
|
|
|
|
que_graph_free_recursive(prebuilt->upd_graph);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (prebuilt->blob_heap) {
|
|
|
|
mem_heap_free(prebuilt->blob_heap);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (prebuilt->old_vers_heap) {
|
|
|
|
mem_heap_free(prebuilt->old_vers_heap);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < MYSQL_FETCH_CACHE_SIZE; i++) {
|
|
|
|
if (prebuilt->fetch_cache[i] != NULL) {
|
|
|
|
mem_free(prebuilt->fetch_cache[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mem_heap_free(prebuilt->heap);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Updates the transaction pointers in query graphs stored in the prebuilt
|
|
|
|
struct. */
|
|
|
|
|
|
|
|
void
|
|
|
|
row_update_prebuilt_trx(
|
|
|
|
/*====================*/
|
|
|
|
/* out: prebuilt dtuple */
|
|
|
|
row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL
|
|
|
|
handle */
|
|
|
|
trx_t* trx) /* in: transaction handle */
|
|
|
|
{
|
|
|
|
prebuilt->trx = trx;
|
|
|
|
|
|
|
|
if (prebuilt->ins_graph) {
|
|
|
|
prebuilt->ins_graph->trx = trx;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (prebuilt->upd_graph) {
|
|
|
|
prebuilt->upd_graph->trx = trx;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (prebuilt->sel_graph) {
|
|
|
|
prebuilt->sel_graph->trx = trx;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Gets pointer to a prebuilt dtuple used in insertions. If the insert graph
|
|
|
|
has not yet been built in the prebuilt struct, then this function first
|
|
|
|
builds it. */
|
|
|
|
static
|
|
|
|
dtuple_t*
|
|
|
|
row_get_prebuilt_insert_row(
|
|
|
|
/*========================*/
|
|
|
|
/* out: prebuilt dtuple */
|
|
|
|
row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
|
|
|
|
handle */
|
|
|
|
{
|
|
|
|
ins_node_t* node;
|
|
|
|
dtuple_t* row;
|
|
|
|
dict_table_t* table = prebuilt->table;
|
|
|
|
|
|
|
|
ut_ad(prebuilt && table && prebuilt->trx);
|
|
|
|
|
|
|
|
if (prebuilt->ins_node == NULL) {
|
|
|
|
|
|
|
|
/* Not called before for this handle: create an insert node
|
|
|
|
and query graph to the prebuilt struct */
|
|
|
|
|
|
|
|
node = ins_node_create(INS_DIRECT, table, prebuilt->heap);
|
|
|
|
|
|
|
|
prebuilt->ins_node = node;
|
|
|
|
|
|
|
|
if (prebuilt->ins_upd_rec_buff == NULL) {
|
|
|
|
prebuilt->ins_upd_rec_buff = mem_heap_alloc(
|
|
|
|
prebuilt->heap,
|
|
|
|
prebuilt->mysql_row_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
row = dtuple_create(prebuilt->heap,
|
|
|
|
dict_table_get_n_cols(table));
|
|
|
|
|
|
|
|
dict_table_copy_types(row, table);
|
|
|
|
|
|
|
|
ins_node_set_new_row(node, row);
|
|
|
|
|
|
|
|
prebuilt->ins_graph =
|
|
|
|
que_node_get_parent(
|
|
|
|
pars_complete_graph_for_exec(node,
|
|
|
|
prebuilt->trx,
|
|
|
|
prebuilt->heap));
|
|
|
|
prebuilt->ins_graph->state = QUE_FORK_ACTIVE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return(prebuilt->ins_node->row);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Updates the table modification counter and calculates new estimates
|
|
|
|
for table and index statistics if necessary. */
|
|
|
|
UNIV_INLINE
|
|
|
|
void
|
|
|
|
row_update_statistics_if_needed(
|
|
|
|
/*============================*/
|
|
|
|
row_prebuilt_t* prebuilt) /* in: prebuilt struct */
|
|
|
|
{
|
|
|
|
ulint counter;
|
|
|
|
ulint old_counter;
|
|
|
|
|
|
|
|
counter = prebuilt->table->stat_modif_counter;
|
|
|
|
|
|
|
|
counter += prebuilt->mysql_row_len;
|
|
|
|
prebuilt->table->stat_modif_counter = counter;
|
|
|
|
|
|
|
|
old_counter = prebuilt->table->stat_last_estimate_counter;
|
|
|
|
|
|
|
|
if (counter - old_counter >= DICT_STAT_CALCULATE_INTERVAL
|
|
|
|
|| counter - old_counter >=
|
|
|
|
(UNIV_PAGE_SIZE
|
|
|
|
* prebuilt->table->stat_clustered_index_size / 2)) {
|
|
|
|
|
|
|
|
dict_update_statistics(prebuilt->table);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Does an insert for MySQL. */
|
|
|
|
|
|
|
|
int
|
|
|
|
row_insert_for_mysql(
|
|
|
|
/*=================*/
|
|
|
|
/* out: error code or DB_SUCCESS */
|
|
|
|
byte* mysql_rec, /* in: row in the MySQL format */
|
|
|
|
row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
|
|
|
|
handle */
|
|
|
|
{
|
|
|
|
trx_savept_t savept;
|
|
|
|
que_thr_t* thr;
|
|
|
|
ulint err;
|
|
|
|
ibool was_lock_wait;
|
|
|
|
trx_t* trx = prebuilt->trx;
|
|
|
|
ins_node_t* node = prebuilt->ins_node;
|
|
|
|
|
|
|
|
ut_ad(trx);
|
|
|
|
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
|
|
|
|
|
|
|
if (node == NULL) {
|
|
|
|
row_get_prebuilt_insert_row(prebuilt);
|
|
|
|
node = prebuilt->ins_node;
|
|
|
|
}
|
|
|
|
|
ut0ut.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
mem0pool.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
os0file.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
os0shm.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
os0sync.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
os0thread.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
page0page.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
que0que.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
row0ins.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
row0mysql.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
row0sel.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
row0upd.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
row0vers.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
srv0srv.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
srv0start.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
sync0arr.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
sync0rw.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
sync0sync.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
trx0rec.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
trx0trx.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
srv0srv.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
sync0rw.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
sync0sync.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
ut0dbg.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
lock0lock.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
log0log.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
log0recv.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
ibuf0ibuf.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
buf0buf.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
buf0buf.ic Fixes for 64-bit Linux, bug fixes, compiler warning fixes
hash0hash.ic Fixes for 64-bit Linux, bug fixes, compiler warning fixes
mach0data.ic Fixes for 64-bit Linux, bug fixes, compiler warning fixes
mem0mem.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
mem0pool.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
mtr0mtr.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
os0file.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
os0sync.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
os0sync.ic Fixes for 64-bit Linux, bug fixes, compiler warning fixes
os0thread.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
univ.i Fixes for 64-bit Linux, bug fixes, compiler warning fixes
row0mysql.ic Fixes for 64-bit Linux, bug fixes, compiler warning fixes
com0shm.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
data0data.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
data0type.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
dict0crea.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
dict0dict.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
fil0fil.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
fsp0fsp.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
fut0lst.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
btr0sea.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
buf0buf.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
buf0flu.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
btr0btr.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
btr0cur.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/btr/btr0btr.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/btr/btr0cur.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/btr/btr0sea.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/buf/buf0buf.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/buf/buf0flu.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/com/com0shm.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/data/data0data.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/data/data0type.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/dict/dict0crea.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/dict/dict0dict.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/fil/fil0fil.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/fsp/fsp0fsp.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/fut/fut0lst.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/ibuf/ibuf0ibuf.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/buf0buf.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/buf0buf.ic:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/hash0hash.ic:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/mach0data.ic:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/mem0mem.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/mem0pool.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/mtr0mtr.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/os0file.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/os0sync.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/os0sync.ic:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/os0thread.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/row0mysql.ic:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/univ.i:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/srv0srv.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/sync0rw.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/sync0sync.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/ut0dbg.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/lock/lock0lock.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/log/log0log.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/log/log0recv.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/mem/mem0pool.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/os/os0file.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/os/os0shm.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/os/os0sync.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/os/os0thread.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/page/page0page.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/que/que0que.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/row/row0ins.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/row/row0mysql.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/row/row0sel.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/row/row0upd.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/row/row0vers.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/srv/srv0srv.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/srv/srv0start.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/sync/sync0arr.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/sync/sync0rw.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/sync/sync0sync.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/trx/trx0rec.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/trx/trx0trx.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/ut/ut0ut.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
2001-03-02 16:33:11 +01:00
|
|
|
row_mysql_convert_row_to_innobase(node->row, prebuilt, mysql_rec);
|
|
|
|
|
2001-02-17 13:19:19 +01:00
|
|
|
savept = trx_savept_take(trx);
|
|
|
|
|
|
|
|
thr = que_fork_get_first_thr(prebuilt->ins_graph);
|
|
|
|
|
|
|
|
if (prebuilt->sql_stat_start) {
|
|
|
|
node->state = INS_NODE_SET_IX_LOCK;
|
|
|
|
prebuilt->sql_stat_start = FALSE;
|
|
|
|
} else {
|
|
|
|
node->state = INS_NODE_ALLOC_ROW_ID;
|
|
|
|
}
|
|
|
|
|
|
|
|
que_thr_move_to_run_state_for_mysql(thr, trx);
|
|
|
|
|
|
|
|
run_again:
|
|
|
|
thr->run_node = node;
|
|
|
|
thr->prev_node = node;
|
|
|
|
|
|
|
|
row_ins_step(thr);
|
|
|
|
|
|
|
|
err = trx->error_state;
|
|
|
|
|
|
|
|
if (err != DB_SUCCESS) {
|
|
|
|
que_thr_stop_for_mysql(thr);
|
|
|
|
|
|
|
|
was_lock_wait = row_mysql_handle_errors(&err, trx, thr,
|
|
|
|
&savept);
|
|
|
|
if (was_lock_wait) {
|
|
|
|
goto run_again;
|
|
|
|
}
|
|
|
|
|
|
|
|
return(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
que_thr_stop_for_mysql_no_error(thr, trx);
|
|
|
|
|
|
|
|
prebuilt->table->stat_n_rows++;
|
|
|
|
|
|
|
|
if (prebuilt->table->stat_n_rows == 0) {
|
|
|
|
/* Avoid wrap-over */
|
|
|
|
prebuilt->table->stat_n_rows--;
|
|
|
|
}
|
|
|
|
|
|
|
|
row_update_statistics_if_needed(prebuilt);
|
|
|
|
|
|
|
|
return((int) err);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Builds a dummy query graph used in selects. */
|
|
|
|
|
|
|
|
void
|
|
|
|
row_prebuild_sel_graph(
|
|
|
|
/*===================*/
|
|
|
|
row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
|
|
|
|
handle */
|
|
|
|
{
|
|
|
|
sel_node_t* node;
|
|
|
|
|
|
|
|
ut_ad(prebuilt && prebuilt->trx);
|
|
|
|
|
|
|
|
if (prebuilt->sel_graph == NULL) {
|
|
|
|
|
|
|
|
node = sel_node_create(prebuilt->heap);
|
|
|
|
|
|
|
|
prebuilt->sel_graph =
|
|
|
|
que_node_get_parent(
|
|
|
|
pars_complete_graph_for_exec(node,
|
|
|
|
prebuilt->trx,
|
|
|
|
prebuilt->heap));
|
|
|
|
|
|
|
|
prebuilt->sel_graph->state = QUE_FORK_ACTIVE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Gets pointer to a prebuilt update vector used in updates. If the update
|
|
|
|
graph has not yet been built in the prebuilt struct, then this function
|
|
|
|
first builds it. */
|
|
|
|
|
|
|
|
upd_t*
|
|
|
|
row_get_prebuilt_update_vector(
|
|
|
|
/*===========================*/
|
|
|
|
/* out: prebuilt update vector */
|
|
|
|
row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
|
|
|
|
handle */
|
|
|
|
{
|
|
|
|
dict_table_t* table = prebuilt->table;
|
|
|
|
upd_node_t* node;
|
|
|
|
|
|
|
|
ut_ad(prebuilt && table && prebuilt->trx);
|
|
|
|
|
|
|
|
if (prebuilt->upd_node == NULL) {
|
|
|
|
|
|
|
|
/* Not called before for this handle: create an update node
|
|
|
|
and query graph to the prebuilt struct */
|
|
|
|
|
|
|
|
node = upd_node_create(prebuilt->heap);
|
|
|
|
|
|
|
|
prebuilt->upd_node = node;
|
|
|
|
|
|
|
|
node->in_mysql_interface = TRUE;
|
|
|
|
node->is_delete = FALSE;
|
|
|
|
node->searched_update = FALSE;
|
|
|
|
node->select_will_do_update = FALSE;
|
|
|
|
node->select = NULL;
|
|
|
|
node->pcur = btr_pcur_create_for_mysql();
|
|
|
|
node->table = table;
|
|
|
|
|
|
|
|
node->update = upd_create(dict_table_get_n_cols(table),
|
|
|
|
prebuilt->heap);
|
|
|
|
UT_LIST_INIT(node->columns);
|
|
|
|
node->has_clust_rec_x_lock = TRUE;
|
|
|
|
node->cmpl_info = 0;
|
|
|
|
|
|
|
|
node->table_sym = NULL;
|
|
|
|
node->col_assign_list = NULL;
|
|
|
|
|
|
|
|
prebuilt->upd_graph =
|
|
|
|
que_node_get_parent(
|
|
|
|
pars_complete_graph_for_exec(node,
|
|
|
|
prebuilt->trx,
|
|
|
|
prebuilt->heap));
|
|
|
|
prebuilt->upd_graph->state = QUE_FORK_ACTIVE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return(prebuilt->upd_node->update);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Does an update or delete of a row for MySQL. */
|
|
|
|
|
|
|
|
int
|
|
|
|
row_update_for_mysql(
|
|
|
|
/*=================*/
|
|
|
|
/* out: error code or DB_SUCCESS */
|
|
|
|
byte* mysql_rec, /* in: the row to be updated, in
|
|
|
|
the MySQL format */
|
|
|
|
row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
|
|
|
|
handle */
|
|
|
|
{
|
|
|
|
trx_savept_t savept;
|
|
|
|
ulint err;
|
|
|
|
que_thr_t* thr;
|
|
|
|
ibool was_lock_wait;
|
|
|
|
dict_index_t* clust_index;
|
2001-03-03 18:15:53 +01:00
|
|
|
/* ulint ref_len; */
|
2001-02-17 13:19:19 +01:00
|
|
|
upd_node_t* node;
|
|
|
|
dict_table_t* table = prebuilt->table;
|
|
|
|
trx_t* trx = prebuilt->trx;
|
2001-03-03 18:15:53 +01:00
|
|
|
/* mem_heap_t* heap;
|
2001-02-17 13:19:19 +01:00
|
|
|
dtuple_t* search_tuple;
|
|
|
|
dtuple_t* row_tuple;
|
2001-03-03 18:15:53 +01:00
|
|
|
mtr_t mtr; */
|
2001-02-17 13:19:19 +01:00
|
|
|
|
|
|
|
ut_ad(prebuilt && trx);
|
|
|
|
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
|
|
|
|
|
|
|
node = prebuilt->upd_node;
|
|
|
|
|
|
|
|
clust_index = dict_table_get_first_index(table);
|
|
|
|
|
2001-03-07 16:22:27 +01:00
|
|
|
if (prebuilt->pcur->btr_cur.index == clust_index) {
|
2001-03-03 18:15:53 +01:00
|
|
|
btr_pcur_copy_stored_position(node->pcur, prebuilt->pcur);
|
2001-03-07 16:22:27 +01:00
|
|
|
} else {
|
|
|
|
btr_pcur_copy_stored_position(node->pcur, prebuilt->clust_pcur);
|
2001-03-03 18:15:53 +01:00
|
|
|
}
|
2001-03-07 16:22:27 +01:00
|
|
|
|
|
|
|
ut_a(node->pcur->rel_pos == BTR_PCUR_ON);
|
|
|
|
|
|
|
|
/* MySQL seems to call rnd_pos before updating each row it
|
|
|
|
has cached: we can get the correct cursor position from
|
|
|
|
prebuilt->pcur; NOTE that we cannot build the row reference
|
|
|
|
from mysql_rec if the clustered index was automatically
|
|
|
|
generated for the table: MySQL does not know anything about
|
|
|
|
the row id used as the clustered index key */
|
|
|
|
|
2001-03-03 18:15:53 +01:00
|
|
|
#ifdef notdefined
|
2001-02-17 13:19:19 +01:00
|
|
|
/* We have to search for the correct cursor position */
|
|
|
|
|
|
|
|
ref_len = dict_index_get_n_unique(clust_index);
|
|
|
|
|
|
|
|
heap = mem_heap_create(450);
|
|
|
|
|
|
|
|
row_tuple = dtuple_create(heap, dict_table_get_n_cols(table));
|
|
|
|
dict_table_copy_types(row_tuple, table);
|
|
|
|
|
|
|
|
if (prebuilt->ins_upd_rec_buff == NULL) {
|
|
|
|
prebuilt->ins_upd_rec_buff = mem_heap_alloc(prebuilt->heap,
|
|
|
|
prebuilt->mysql_row_len);
|
|
|
|
}
|
|
|
|
|
ut0ut.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
mem0pool.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
os0file.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
os0shm.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
os0sync.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
os0thread.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
page0page.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
que0que.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
row0ins.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
row0mysql.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
row0sel.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
row0upd.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
row0vers.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
srv0srv.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
srv0start.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
sync0arr.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
sync0rw.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
sync0sync.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
trx0rec.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
trx0trx.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
srv0srv.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
sync0rw.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
sync0sync.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
ut0dbg.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
lock0lock.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
log0log.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
log0recv.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
ibuf0ibuf.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
buf0buf.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
buf0buf.ic Fixes for 64-bit Linux, bug fixes, compiler warning fixes
hash0hash.ic Fixes for 64-bit Linux, bug fixes, compiler warning fixes
mach0data.ic Fixes for 64-bit Linux, bug fixes, compiler warning fixes
mem0mem.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
mem0pool.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
mtr0mtr.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
os0file.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
os0sync.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
os0sync.ic Fixes for 64-bit Linux, bug fixes, compiler warning fixes
os0thread.h Fixes for 64-bit Linux, bug fixes, compiler warning fixes
univ.i Fixes for 64-bit Linux, bug fixes, compiler warning fixes
row0mysql.ic Fixes for 64-bit Linux, bug fixes, compiler warning fixes
com0shm.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
data0data.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
data0type.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
dict0crea.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
dict0dict.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
fil0fil.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
fsp0fsp.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
fut0lst.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
btr0sea.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
buf0buf.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
buf0flu.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
btr0btr.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
btr0cur.c Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/btr/btr0btr.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/btr/btr0cur.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/btr/btr0sea.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/buf/buf0buf.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/buf/buf0flu.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/com/com0shm.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/data/data0data.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/data/data0type.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/dict/dict0crea.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/dict/dict0dict.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/fil/fil0fil.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/fsp/fsp0fsp.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/fut/fut0lst.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/ibuf/ibuf0ibuf.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/buf0buf.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/buf0buf.ic:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/hash0hash.ic:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/mach0data.ic:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/mem0mem.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/mem0pool.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/mtr0mtr.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/os0file.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/os0sync.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/os0sync.ic:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/os0thread.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/row0mysql.ic:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/univ.i:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/srv0srv.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/sync0rw.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/sync0sync.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/include/ut0dbg.h:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/lock/lock0lock.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/log/log0log.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/log/log0recv.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/mem/mem0pool.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/os/os0file.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/os/os0shm.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/os/os0sync.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/os/os0thread.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/page/page0page.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/que/que0que.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/row/row0ins.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/row/row0mysql.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/row/row0sel.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/row/row0upd.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/row/row0vers.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/srv/srv0srv.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/srv/srv0start.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/sync/sync0arr.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/sync/sync0rw.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/sync/sync0sync.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/trx/trx0rec.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/trx/trx0trx.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
innobase/ut/ut0ut.c:
Fixes for 64-bit Linux, bug fixes, compiler warning fixes
2001-03-02 16:33:11 +01:00
|
|
|
row_mysql_convert_row_to_innobase(row_tuple, prebuilt, mysql_rec);
|
2001-02-17 13:19:19 +01:00
|
|
|
|
|
|
|
search_tuple = dtuple_create(heap, ref_len);
|
|
|
|
|
|
|
|
row_build_row_ref_from_row(search_tuple, table, row_tuple);
|
|
|
|
|
|
|
|
mtr_start(&mtr);
|
|
|
|
|
|
|
|
btr_pcur_open_with_no_init(clust_index, search_tuple, PAGE_CUR_LE,
|
|
|
|
BTR_SEARCH_LEAF, node->pcur, 0, &mtr);
|
|
|
|
|
|
|
|
btr_pcur_store_position(node->pcur, &mtr);
|
|
|
|
|
|
|
|
mtr_commit(&mtr);
|
|
|
|
|
|
|
|
mem_heap_free(heap);
|
2001-03-03 18:15:53 +01:00
|
|
|
#endif
|
2001-02-17 13:19:19 +01:00
|
|
|
savept = trx_savept_take(trx);
|
|
|
|
|
|
|
|
thr = que_fork_get_first_thr(prebuilt->upd_graph);
|
|
|
|
|
|
|
|
node->state = UPD_NODE_UPDATE_CLUSTERED;
|
|
|
|
|
|
|
|
ut_ad(!prebuilt->sql_stat_start);
|
|
|
|
|
|
|
|
que_thr_move_to_run_state_for_mysql(thr, trx);
|
|
|
|
run_again:
|
|
|
|
thr->run_node = node;
|
|
|
|
thr->prev_node = node;
|
|
|
|
|
|
|
|
row_upd_step(thr);
|
|
|
|
|
|
|
|
err = trx->error_state;
|
|
|
|
|
|
|
|
if (err != DB_SUCCESS) {
|
|
|
|
que_thr_stop_for_mysql(thr);
|
|
|
|
|
|
|
|
if (err == DB_RECORD_NOT_FOUND) {
|
|
|
|
trx->error_state = DB_SUCCESS;
|
|
|
|
|
|
|
|
return((int) err);
|
|
|
|
}
|
|
|
|
|
|
|
|
was_lock_wait = row_mysql_handle_errors(&err, trx, thr,
|
|
|
|
&savept);
|
|
|
|
if (was_lock_wait) {
|
|
|
|
goto run_again;
|
|
|
|
}
|
|
|
|
|
|
|
|
return(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
que_thr_stop_for_mysql_no_error(thr, trx);
|
|
|
|
|
|
|
|
if (prebuilt->upd_node->is_delete) {
|
|
|
|
if (prebuilt->table->stat_n_rows > 0) {
|
|
|
|
prebuilt->table->stat_n_rows--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
row_update_statistics_if_needed(prebuilt);
|
|
|
|
|
|
|
|
return((int) err);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Checks if a table is such that we automatically created a clustered
|
|
|
|
index on it (on row id). */
|
|
|
|
|
|
|
|
ibool
|
|
|
|
row_table_got_default_clust_index(
|
|
|
|
/*==============================*/
|
|
|
|
dict_table_t* table)
|
|
|
|
{
|
|
|
|
dict_index_t* clust_index;
|
|
|
|
|
|
|
|
clust_index = dict_table_get_first_index(table);
|
|
|
|
|
|
|
|
if (dtype_get_mtype(dict_index_get_nth_type(clust_index, 0))
|
|
|
|
== DATA_SYS) {
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
trx0trx.h Innobase now returns the key number in a duplicate key error, removed innobase/include from make dirs
row0ins.c Innobase now returns the key number in a duplicate key error, removed innobase/include from make dirs
row0mysql.c Innobase now returns the key number in a duplicate key error, removed innobase/include from make dirs
row0mysql.h Innobase now returns the key number in a duplicate key error, removed innobase/include from make dirs
ha_innobase.cc Innobase now returns the key number in a duplicate key error, removed innobase/include from make dirs
sql/ha_innobase.cc:
Innobase now returns the key number in a duplicate key error, removed innobase/include from make dirs
innobase/include/row0mysql.h:
Innobase now returns the key number in a duplicate key error, removed innobase/include from make dirs
innobase/include/trx0trx.h:
Innobase now returns the key number in a duplicate key error, removed innobase/include from make dirs
innobase/row/row0ins.c:
Innobase now returns the key number in a duplicate key error, removed innobase/include from make dirs
innobase/row/row0mysql.c:
Innobase now returns the key number in a duplicate key error, removed innobase/include from make dirs
2001-03-06 18:45:10 +01:00
|
|
|
/*************************************************************************
|
|
|
|
Calculates the key number used inside MySQL for an Innobase index. We have
|
|
|
|
to take into account if we generated a default clustered index for the table */
|
|
|
|
|
|
|
|
ulint
|
|
|
|
row_get_mysql_key_number_for_index(
|
|
|
|
/*===============================*/
|
|
|
|
dict_index_t* index)
|
|
|
|
{
|
|
|
|
dict_index_t* ind;
|
|
|
|
ulint i;
|
|
|
|
|
|
|
|
ut_a(index);
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
ind = dict_table_get_first_index(index->table);
|
|
|
|
|
|
|
|
while (index != ind) {
|
|
|
|
ind = dict_table_get_next_index(ind);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (row_table_got_default_clust_index(index->table)) {
|
|
|
|
ut_a(i > 0);
|
|
|
|
i--;
|
|
|
|
}
|
|
|
|
|
|
|
|
return(i);
|
|
|
|
}
|
|
|
|
|
2001-02-17 13:19:19 +01:00
|
|
|
/*************************************************************************
|
|
|
|
Does a table creation operation for MySQL. */
|
|
|
|
|
|
|
|
int
|
|
|
|
row_create_table_for_mysql(
|
|
|
|
/*=======================*/
|
|
|
|
/* out: error code or DB_SUCCESS */
|
|
|
|
dict_table_t* table, /* in: table definition */
|
|
|
|
trx_t* trx) /* in: transaction handle */
|
|
|
|
{
|
|
|
|
tab_node_t* node;
|
|
|
|
mem_heap_t* heap;
|
|
|
|
que_thr_t* thr;
|
|
|
|
ulint err;
|
|
|
|
|
|
|
|
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
|
|
|
|
|
|
|
/* Serialize data dictionary operations with dictionary mutex:
|
|
|
|
no deadlocks can occur then in these operations */
|
|
|
|
|
|
|
|
mutex_enter(&(dict_sys->mutex));
|
|
|
|
|
|
|
|
heap = mem_heap_create(512);
|
|
|
|
|
|
|
|
trx->dict_operation = TRUE;
|
|
|
|
|
|
|
|
node = tab_create_graph_create(table, heap);
|
|
|
|
|
|
|
|
thr = pars_complete_graph_for_exec(node, trx, heap);
|
|
|
|
|
|
|
|
ut_a(thr == que_fork_start_command(que_node_get_parent(thr),
|
|
|
|
SESS_COMM_EXECUTE, 0));
|
|
|
|
que_run_threads(thr);
|
|
|
|
|
|
|
|
err = trx->error_state;
|
|
|
|
|
|
|
|
if (err != DB_SUCCESS) {
|
|
|
|
/* We have special error handling here */
|
2001-03-08 15:55:14 +01:00
|
|
|
|
2001-02-17 13:19:19 +01:00
|
|
|
trx->error_state = DB_SUCCESS;
|
|
|
|
|
|
|
|
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
|
|
|
|
2001-03-08 15:55:14 +01:00
|
|
|
if (err == DB_OUT_OF_FILE_SPACE) {
|
|
|
|
row_drop_table_for_mysql(table->name, trx, TRUE);
|
|
|
|
} else {
|
|
|
|
assert(err == DB_DUPLICATE_KEY);
|
|
|
|
fprintf(stderr,
|
|
|
|
"Innobase: error: table %s already exists in Innobase data dictionary\n",
|
|
|
|
table->name);
|
|
|
|
}
|
2001-02-17 13:19:19 +01:00
|
|
|
|
|
|
|
trx->error_state = DB_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
mutex_exit(&(dict_sys->mutex));
|
|
|
|
que_graph_free((que_t*) que_node_get_parent(thr));
|
|
|
|
|
|
|
|
return((int) err);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Does an index creation operation for MySQL. TODO: currently failure
|
|
|
|
to create an index results in dropping the whole table! This is no problem
|
|
|
|
currently as all indexes must be created at the same time as the table. */
|
|
|
|
|
|
|
|
int
|
|
|
|
row_create_index_for_mysql(
|
|
|
|
/*=======================*/
|
|
|
|
/* out: error number or DB_SUCCESS */
|
|
|
|
dict_index_t* index, /* in: index defintion */
|
|
|
|
trx_t* trx) /* in: transaction handle */
|
|
|
|
{
|
|
|
|
ind_node_t* node;
|
|
|
|
mem_heap_t* heap;
|
|
|
|
que_thr_t* thr;
|
|
|
|
ulint err;
|
|
|
|
|
|
|
|
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
|
|
|
|
|
|
|
/* Serialize data dictionary operations with dictionary mutex:
|
|
|
|
no deadlocks can occur then in these operations */
|
|
|
|
|
|
|
|
mutex_enter(&(dict_sys->mutex));
|
|
|
|
|
|
|
|
heap = mem_heap_create(512);
|
|
|
|
|
|
|
|
trx->dict_operation = TRUE;
|
|
|
|
|
|
|
|
node = ind_create_graph_create(index, heap);
|
|
|
|
|
|
|
|
thr = pars_complete_graph_for_exec(node, trx, heap);
|
|
|
|
|
|
|
|
ut_a(thr == que_fork_start_command(que_node_get_parent(thr),
|
|
|
|
SESS_COMM_EXECUTE, 0));
|
|
|
|
que_run_threads(thr);
|
|
|
|
|
|
|
|
err = trx->error_state;
|
|
|
|
|
|
|
|
if (err != DB_SUCCESS) {
|
|
|
|
/* We have special error handling here */
|
|
|
|
ut_a(err == DB_OUT_OF_FILE_SPACE);
|
|
|
|
|
|
|
|
trx->error_state = DB_SUCCESS;
|
|
|
|
|
|
|
|
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
|
|
|
|
|
|
|
row_drop_table_for_mysql(index->table_name, trx, TRUE);
|
|
|
|
|
|
|
|
trx->error_state = DB_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
mutex_exit(&(dict_sys->mutex));
|
|
|
|
|
|
|
|
que_graph_free((que_t*) que_node_get_parent(thr));
|
|
|
|
|
|
|
|
return((int) err);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Drops a table for MySQL. */
|
|
|
|
|
|
|
|
int
|
|
|
|
row_drop_table_for_mysql(
|
|
|
|
/*=====================*/
|
|
|
|
/* out: error code or DB_SUCCESS */
|
|
|
|
char* name, /* in: table name */
|
|
|
|
trx_t* trx, /* in: transaction handle */
|
|
|
|
ibool has_dict_mutex) /* in: TRUE if the caller already owns the
|
|
|
|
dictionary system mutex */
|
|
|
|
{
|
|
|
|
dict_table_t* table;
|
|
|
|
que_thr_t* thr;
|
|
|
|
que_t* graph;
|
|
|
|
ulint err;
|
|
|
|
char* str1;
|
|
|
|
char* str2;
|
|
|
|
ulint len;
|
|
|
|
char buf[10000];
|
|
|
|
retry:
|
|
|
|
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
|
|
|
ut_a(name != NULL);
|
|
|
|
|
|
|
|
/* We use the private SQL parser of Innobase to generate the
|
|
|
|
query graphs needed in deleting the dictionary data from system
|
|
|
|
tables in Innobase. Deleting a row from SYS_INDEXES table also
|
|
|
|
frees the file segments of the B-tree associated with the index. */
|
|
|
|
|
|
|
|
str1 =
|
|
|
|
"PROCEDURE DROP_TABLE_PROC () IS\n"
|
|
|
|
"table_id CHAR;\n"
|
|
|
|
"index_id CHAR;\n"
|
|
|
|
"found INT;\n"
|
|
|
|
"BEGIN\n"
|
|
|
|
"SELECT ID INTO table_id\n"
|
|
|
|
"FROM SYS_TABLES\n"
|
|
|
|
"WHERE NAME ='";
|
|
|
|
|
|
|
|
str2 =
|
|
|
|
"';\n"
|
|
|
|
"IF (SQL % NOTFOUND) THEN\n"
|
|
|
|
" COMMIT WORK;\n"
|
|
|
|
" RETURN;\n"
|
|
|
|
"END IF;\n"
|
|
|
|
"found := 1;\n"
|
|
|
|
"WHILE found = 1 LOOP\n"
|
|
|
|
" SELECT ID INTO index_id\n"
|
|
|
|
" FROM SYS_INDEXES\n"
|
|
|
|
" WHERE TABLE_ID = table_id;\n"
|
|
|
|
" IF (SQL % NOTFOUND) THEN\n"
|
|
|
|
" found := 0;\n"
|
|
|
|
" ELSE"
|
|
|
|
" DELETE FROM SYS_FIELDS WHERE INDEX_ID = index_id;\n"
|
|
|
|
" DELETE FROM SYS_INDEXES WHERE ID = index_id;\n"
|
|
|
|
" END IF;\n"
|
|
|
|
"END LOOP;\n"
|
|
|
|
"DELETE FROM SYS_COLUMNS WHERE TABLE_ID = table_id;\n"
|
|
|
|
"DELETE FROM SYS_TABLES WHERE ID = table_id;\n"
|
|
|
|
"COMMIT WORK;\n"
|
|
|
|
"END;\n";
|
|
|
|
|
|
|
|
len = ut_strlen(str1);
|
|
|
|
|
|
|
|
ut_memcpy(buf, str1, len);
|
|
|
|
ut_memcpy(buf + len, name, ut_strlen(name));
|
|
|
|
|
|
|
|
len += ut_strlen(name);
|
|
|
|
|
|
|
|
ut_memcpy(buf + len, str2, ut_strlen(str2) + 1);
|
|
|
|
|
|
|
|
/* Serialize data dictionary operations with dictionary mutex:
|
|
|
|
no deadlocks can occur then in these operations */
|
|
|
|
|
|
|
|
if (!has_dict_mutex) {
|
|
|
|
mutex_enter(&(dict_sys->mutex));
|
|
|
|
}
|
|
|
|
|
|
|
|
graph = pars_sql(buf);
|
|
|
|
|
|
|
|
ut_a(graph);
|
|
|
|
|
|
|
|
graph->trx = trx;
|
|
|
|
trx->graph = NULL;
|
|
|
|
|
|
|
|
graph->fork_type = QUE_FORK_MYSQL_INTERFACE;
|
|
|
|
|
|
|
|
/* Prevent purge from running while we are dropping the table */
|
|
|
|
rw_lock_s_lock(&(purge_sys->purge_is_running));
|
|
|
|
|
|
|
|
table = dict_table_get_low(name);
|
|
|
|
|
|
|
|
if (!table) {
|
|
|
|
err = DB_TABLE_NOT_FOUND;
|
|
|
|
|
|
|
|
goto funct_exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if there are any locks on the table: if yes, it cannot
|
|
|
|
be dropped: we have to wait for the locks to be released */
|
|
|
|
|
|
|
|
if (lock_is_on_table(table)) {
|
|
|
|
|
|
|
|
err = DB_TABLE_IS_BEING_USED;
|
|
|
|
|
|
|
|
goto funct_exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO: check that MySQL prevents users from accessing the table
|
|
|
|
after this function row_drop_table_for_mysql has been called:
|
|
|
|
otherwise anyone with an open handle to the table could, for example,
|
|
|
|
come to read the table! */
|
|
|
|
|
|
|
|
trx->dict_operation = TRUE;
|
|
|
|
trx->table_id = table->id;
|
|
|
|
|
|
|
|
ut_a(thr = que_fork_start_command(graph, SESS_COMM_EXECUTE, 0));
|
|
|
|
|
|
|
|
que_run_threads(thr);
|
|
|
|
|
|
|
|
err = trx->error_state;
|
|
|
|
|
|
|
|
if (err != DB_SUCCESS) {
|
|
|
|
ut_a(err == DB_OUT_OF_FILE_SPACE);
|
|
|
|
|
|
|
|
err = DB_MUST_GET_MORE_FILE_SPACE;
|
|
|
|
|
|
|
|
row_mysql_handle_errors(&err, trx, thr, NULL);
|
|
|
|
|
|
|
|
ut_a(0);
|
|
|
|
} else {
|
|
|
|
dict_table_remove_from_cache(table);
|
|
|
|
}
|
|
|
|
funct_exit:
|
|
|
|
rw_lock_s_unlock(&(purge_sys->purge_is_running));
|
|
|
|
|
|
|
|
if (!has_dict_mutex) {
|
|
|
|
mutex_exit(&(dict_sys->mutex));
|
|
|
|
}
|
|
|
|
|
|
|
|
que_graph_free(graph);
|
|
|
|
|
|
|
|
if (err == DB_TABLE_IS_BEING_USED) {
|
|
|
|
os_thread_sleep(200000);
|
|
|
|
|
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
|
|
|
|
return((int) err);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Renames a table for MySQL. */
|
|
|
|
|
|
|
|
int
|
|
|
|
row_rename_table_for_mysql(
|
|
|
|
/*=======================*/
|
|
|
|
/* out: error code or DB_SUCCESS */
|
|
|
|
char* old_name, /* in: old table name */
|
|
|
|
char* new_name, /* in: new table name */
|
|
|
|
trx_t* trx) /* in: transaction handle */
|
|
|
|
{
|
|
|
|
dict_table_t* table;
|
|
|
|
que_thr_t* thr;
|
|
|
|
que_t* graph;
|
|
|
|
ulint err;
|
|
|
|
char* str1;
|
|
|
|
char* str2;
|
|
|
|
char* str3;
|
|
|
|
ulint len;
|
|
|
|
char buf[10000];
|
|
|
|
|
|
|
|
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
|
|
|
ut_a(old_name != NULL);
|
|
|
|
ut_a(new_name != NULL);
|
|
|
|
|
|
|
|
str1 =
|
|
|
|
"PROCEDURE RENAME_TABLE_PROC () IS\n"
|
|
|
|
"BEGIN\n"
|
|
|
|
"UPDATE SYS_TABLES SET NAME ='";
|
|
|
|
|
|
|
|
str2 =
|
|
|
|
"' WHERE NAME = '";
|
|
|
|
|
|
|
|
str3 =
|
|
|
|
"';\n"
|
|
|
|
"COMMIT WORK;\n"
|
|
|
|
"END;\n";
|
|
|
|
|
|
|
|
len = ut_strlen(str1);
|
|
|
|
|
|
|
|
ut_memcpy(buf, str1, len);
|
|
|
|
|
|
|
|
ut_memcpy(buf + len, new_name, ut_strlen(new_name));
|
|
|
|
|
|
|
|
len += ut_strlen(new_name);
|
|
|
|
|
|
|
|
ut_memcpy(buf + len, str2, ut_strlen(str2));
|
|
|
|
|
|
|
|
len += ut_strlen(str2);
|
|
|
|
|
|
|
|
ut_memcpy(buf + len, old_name, ut_strlen(old_name));
|
|
|
|
|
|
|
|
len += ut_strlen(old_name);
|
|
|
|
|
|
|
|
ut_memcpy(buf + len, str3, ut_strlen(str3) + 1);
|
|
|
|
|
|
|
|
/* Serialize data dictionary operations with dictionary mutex:
|
|
|
|
no deadlocks can occur then in these operations */
|
|
|
|
|
|
|
|
mutex_enter(&(dict_sys->mutex));
|
|
|
|
|
|
|
|
table = dict_table_get_low(old_name);
|
|
|
|
|
|
|
|
graph = pars_sql(buf);
|
|
|
|
|
|
|
|
ut_a(graph);
|
|
|
|
|
|
|
|
graph->trx = trx;
|
|
|
|
trx->graph = NULL;
|
|
|
|
|
|
|
|
graph->fork_type = QUE_FORK_MYSQL_INTERFACE;
|
|
|
|
|
|
|
|
if (!table) {
|
|
|
|
err = DB_TABLE_NOT_FOUND;
|
|
|
|
|
|
|
|
goto funct_exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
ut_a(thr = que_fork_start_command(graph, SESS_COMM_EXECUTE, 0));
|
|
|
|
|
|
|
|
que_run_threads(thr);
|
|
|
|
|
|
|
|
err = trx->error_state;
|
|
|
|
|
|
|
|
if (err != DB_SUCCESS) {
|
|
|
|
row_mysql_handle_errors(&err, trx, thr, NULL);
|
|
|
|
} else {
|
|
|
|
ut_a(dict_table_rename_in_cache(table, new_name));
|
|
|
|
}
|
|
|
|
funct_exit:
|
|
|
|
mutex_exit(&(dict_sys->mutex));
|
|
|
|
|
|
|
|
que_graph_free(graph);
|
|
|
|
|
|
|
|
return((int) err);
|
|
|
|
}
|