summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@hundin.mysql.fi>2002-03-27 01:56:10 +0200
committerunknown <monty@hundin.mysql.fi>2002-03-27 01:56:10 +0200
commit36b38aa503c05efd0479d73dbb40e5e8f13cb986 (patch)
tree6998f99b1790b678ac1558e748e2a8c992bbfa22 /sql
parent6229932f1010c270e2319d8dc3be9670d016546e (diff)
parentbbedc5ebbf8951c3b6a3d4047c40e7934774d58a (diff)
downloadmariadb-git-36b38aa503c05efd0479d73dbb40e5e8f13cb986.tar.gz
merge with 3.23.50
BitKeeper/etc/logging_ok: auto-union BUILD/SETUP.sh: Auto merged Build-tools/Do-compile: Auto merged Build-tools/Do-rpm: Auto merged configure.in: Auto merged include/mysql_com.h: Auto merged innobase/btr/btr0btr.c: Auto merged innobase/btr/btr0cur.c: Auto merged innobase/btr/btr0sea.c: Auto merged innobase/dict/dict0dict.c: Auto merged innobase/dict/dict0load.c: Auto merged innobase/fil/fil0fil.c: Auto merged innobase/fsp/fsp0fsp.c: Auto merged innobase/include/srv0srv.h: Auto merged innobase/include/sync0rw.ic: Auto merged innobase/log/log0log.c: Auto merged innobase/rem/rem0cmp.c: Auto merged innobase/row/row0ins.c: Auto merged innobase/row/row0sel.c: Auto merged innobase/row/row0upd.c: Auto merged innobase/srv/srv0srv.c: Auto merged innobase/srv/srv0start.c: Auto merged myisam/myisampack.c: Auto merged mysql-test/t/range.test: Auto merged scripts/mysqldumpslow.sh: Auto merged sql/ha_innodb.h: Auto merged sql/handler.cc: Auto merged sql/handler.h: Auto merged sql/item.cc: Auto merged sql/item.h: Auto merged sql/item_func.cc: Auto merged sql/item_func.h: Auto merged sql/lock.cc: Auto merged sql/share/Makefile.am: Auto merged sql/sql_rename.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_show.cc: Auto merged support-files/mysql.spec.sh: Auto merged Docs/manual.texi: merge client/mysql.cc: merge client/mysqldump.c: merge innobase/buf/buf0buf.c: merge innobase/os/os0file.c: merge innobase/row/row0mysql.c: merge mysql-test/r/range.result: merge sql/ha_innodb.cc: merge sql/log_event.h: merge sql/mysqld.cc: merge sql/sql_base.cc: merge sql/sql_load.cc: merge
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_innodb.cc502
-rw-r--r--sql/ha_innodb.h3
-rw-r--r--sql/handler.cc5
-rw-r--r--sql/handler.h4
-rw-r--r--sql/item.cc23
-rw-r--r--sql/item.h10
-rw-r--r--sql/item_func.cc10
-rw-r--r--sql/item_func.h6
-rw-r--r--sql/lock.cc7
-rw-r--r--sql/mysqld.cc72
-rw-r--r--sql/share/Makefile.am1
-rw-r--r--sql/sql_base.cc7
-rw-r--r--sql/sql_rename.cc10
-rw-r--r--sql/sql_select.cc28
-rw-r--r--sql/sql_show.cc14
15 files changed, 323 insertions, 379 deletions
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 287b644b5d3..c4b71113c56 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -76,17 +76,32 @@ bool innodb_skip = 0;
uint innobase_init_flags = 0;
ulong innobase_cache_size = 0;
+/* The default values for the following, type long, start-up parameters
+are declared in mysqld.cc: */
+
long innobase_mirrored_log_groups, innobase_log_files_in_group,
innobase_log_file_size, innobase_log_buffer_size,
innobase_buffer_pool_size, innobase_additional_mem_pool_size,
innobase_file_io_threads, innobase_lock_wait_timeout,
- innobase_thread_concurrency, innobase_force_recovery;
-
-char *innobase_data_home_dir;
-char *innobase_log_group_home_dir, *innobase_log_arch_dir;
-char *innobase_unix_file_flush_method;
-my_bool innobase_flush_log_at_trx_commit, innobase_log_archive,
- innobase_use_native_aio, innobase_fast_shutdown;
+ innobase_thread_concurrency, innobase_force_recovery;
+
+/* The default values for the following char* start-up parameters
+are determined in innobase_init below: */
+
+ /* innobase_data_file_path=ibdata:15,idata2:1,... */
+
+char* innobase_data_home_dir = NULL;
+char* innobase_log_group_home_dir = NULL;
+char* innobase_log_arch_dir = NULL;
+char* innobase_unix_file_flush_method = NULL;
+
+/* Below we have boolean-valued start-up parameters, and their default
+values */
+
+my_bool innobase_flush_log_at_trx_commit = FALSE;
+my_bool innobase_log_archive = FALSE;
+my_bool innobase_use_native_aio = FALSE;
+my_bool innobase_fast_shutdown = TRUE;
/*
Set default InnoDB size to 64M, to let users use InnoDB without having
@@ -338,227 +353,6 @@ ha_innobase::update_thd(
}
/*************************************************************************
-Reads the data files and their sizes from a character string given in
-the .cnf file. */
-static
-bool
-innobase_parse_data_file_paths_and_sizes(void)
-/*==========================================*/
- /* out: TRUE if ok, FALSE if parsing
- error */
-{
- char* str;
- char* endp;
- char* path;
- ulint size;
- ulint i = 0;
-
- str = internal_innobase_data_file_path;
-
- /* First calculate the number of data files and check syntax:
- path:size[M];path:size[M]... . Note that a Windows path may
- contain a drive name and a ':'. */
-
- while (*str != '\0') {
- path = str;
-
- while ((*str != ':' && *str != '\0')
- || (*str == ':'
- && (*(str + 1) == '\\' || *(str + 1) == '/'))) {
- str++;
- }
-
- if (*str == '\0') {
- return(FALSE);
- }
-
- str++;
-
- size = strtoul(str, &endp, 10);
-
- str = endp;
-
- if ((*str != 'M') && (*str != 'G')) {
- size = size / (1024 * 1024);
- } else if (*str == 'G') {
- size = size * 1024;
- str++;
- } else {
- str++;
- }
-
- if (strlen(str) >= 6
- && *str == 'n'
- && *(str + 1) == 'e'
- && *(str + 2) == 'w') {
- str += 3;
- }
-
- if (strlen(str) >= 3
- && *str == 'r'
- && *(str + 1) == 'a'
- && *(str + 2) == 'w') {
- str += 3;
- }
-
- if (size == 0) {
- return(FALSE);
- }
-
- i++;
-
- if (*str == ';') {
- str++;
- } else if (*str != '\0') {
-
- return(FALSE);
- }
- }
-
- srv_data_file_names = (char**)ut_malloc(i * sizeof(void*));
- srv_data_file_sizes = (ulint*)ut_malloc(i * sizeof(ulint));
- srv_data_file_is_raw_partition = (ulint*)ut_malloc(i * sizeof(ulint));
-
- srv_n_data_files = i;
-
- /* Then store the actual values to our arrays */
-
- str = internal_innobase_data_file_path;
- i = 0;
-
- while (*str != '\0') {
- path = str;
-
- /* Note that we must ignore the ':' in a Windows path */
-
- while ((*str != ':' && *str != '\0')
- || (*str == ':'
- && (*(str + 1) == '\\' || *(str + 1) == '/'))) {
- str++;
- }
-
- if (*str == ':') {
- /* Make path a null-terminated string */
- *str = '\0';
- str++;
- }
-
- size = strtoul(str, &endp, 10);
-
- str = endp;
-
- if ((*str != 'M') && (*str != 'G')) {
- size = size / (1024 * 1024);
- } else if (*str == 'G') {
- size = size * 1024;
- str++;
- } else {
- str++;
- }
-
- srv_data_file_is_raw_partition[i] = 0;
-
- if (strlen(str) >= 6
- && *str == 'n'
- && *(str + 1) == 'e'
- && *(str + 2) == 'w') {
- str += 3;
- srv_data_file_is_raw_partition[i] = SRV_NEW_RAW;
- }
-
- if (strlen(str) >= 3
- && *str == 'r'
- && *(str + 1) == 'a'
- && *(str + 2) == 'w') {
- str += 3;
-
- if (srv_data_file_is_raw_partition[i] == 0) {
- srv_data_file_is_raw_partition[i] = SRV_OLD_RAW;
- }
- }
-
- srv_data_file_names[i] = path;
- srv_data_file_sizes[i] = size;
-
- i++;
-
- if (*str == ';') {
- str++;
- }
- }
-
- return(TRUE);
-}
-
-/*************************************************************************
-Reads log group home directories from a character string given in
-the .cnf file. */
-static
-bool
-innobase_parse_log_group_home_dirs(void)
-/*====================================*/
- /* out: TRUE if ok, FALSE if parsing
- error */
-{
- char* str;
- char* path;
- ulint i = 0;
-
- str = innobase_log_group_home_dir;
-
- /* First calculate the number of directories and check syntax:
- path;path;... */
-
- while (*str != '\0') {
- path = str;
-
- while (*str != ';' && *str != '\0') {
- str++;
- }
-
- i++;
-
- if (*str == ';') {
- str++;
- } else if (*str != '\0') {
-
- return(FALSE);
- }
- }
-
- if (i != (ulint) innobase_mirrored_log_groups) {
-
- return(FALSE);
- }
-
- srv_log_group_home_dirs = (char**) ut_malloc(i * sizeof(void*));
-
- /* Then store the actual values to our array */
-
- str = innobase_log_group_home_dir;
- i = 0;
-
- while (*str != '\0') {
- path = str;
-
- while (*str != ';' && *str != '\0') {
- str++;
- }
-
- if (*str == ';') {
- *str = '\0';
- str++;
- }
-
- srv_log_group_home_dirs[i] = path;
-
- i++;
- }
-
- return(TRUE);
-}
-
-/*************************************************************************
Opens an InnoDB database. */
bool
@@ -581,9 +375,9 @@ innobase_init(void)
else
{
/* It's better to use current lib, to keep path's short */
- current_lib[0]=FN_CURLIB;
- current_lib[1]=FN_LIBCHAR;
- current_lib[2]=0;
+ current_lib[0] = FN_CURLIB;
+ current_lib[1] = FN_LIBCHAR;
+ current_lib[2] = 0;
default_path=current_lib;
}
@@ -605,12 +399,17 @@ innobase_init(void)
srv_data_home = (innobase_data_home_dir ? innobase_data_home_dir :
default_path);
- srv_logs_home = (char*) "";
srv_arch_dir = (innobase_log_arch_dir ? innobase_log_arch_dir :
default_path);
- ret = innobase_parse_data_file_paths_and_sizes();
-
+ ret = (bool)
+ srv_parse_data_file_paths_and_sizes(innobase_data_file_path,
+ &srv_data_file_names,
+ &srv_data_file_sizes,
+ &srv_data_file_is_raw_partition,
+ &srv_n_data_files,
+ &srv_auto_extend_last_data_file,
+ &srv_last_file_size_max);
if (ret == FALSE) {
sql_print_error("InnoDB: syntax error in innodb_data_file_path");
DBUG_RETURN(TRUE);
@@ -618,12 +417,18 @@ innobase_init(void)
if (!innobase_log_group_home_dir)
innobase_log_group_home_dir= default_path;
- ret = innobase_parse_log_group_home_dirs();
- if (ret == FALSE) {
- DBUG_RETURN(TRUE);
- }
+ ret = (bool)
+ srv_parse_log_group_home_dirs(innobase_log_group_home_dir,
+ &srv_log_group_home_dirs);
+
+ if (ret == FALSE || innobase_mirrored_log_groups != 1) {
+ fprintf(stderr,
+ "InnoDB: syntax error in innodb_log_group_home_dir\n"
+ "InnoDB: or a wrong number of mirrored log groups\n");
+ DBUG_RETURN(TRUE);
+ }
srv_unix_file_flush_method_str = (innobase_unix_file_flush_method ?
innobase_unix_file_flush_method :
(char*)"fdatasync");
@@ -664,10 +469,11 @@ innobase_init(void)
if (err != DB_SUCCESS) {
- DBUG_RETURN(1);
+ DBUG_RETURN(1);
}
+
(void) hash_init(&innobase_open_tables,32,0,0,
- (hash_get_key) innobase_get_key,0,0);
+ (hash_get_key) innobase_get_key,0,0);
pthread_mutex_init(&innobase_mutex,MY_MUTEX_INIT_FAST);
DBUG_RETURN(0);
}
@@ -1353,33 +1159,43 @@ build_template(
clust_index = dict_table_get_first_index_noninline(prebuilt->table);
- if (!prebuilt->in_update_remember_pos) {
+ if (!prebuilt->hint_no_need_to_fetch_extra_cols) {
+ /* We have a hint that we should at least fetch all
+ columns in the key, or all columns in the table */
+
if (prebuilt->read_just_key) {
+ /* MySQL has instructed us that it is enough to
+ fetch the columns in the key */
+
fetch_all_in_key = TRUE;
} else {
/* We are building a temporary table: fetch all
- columns */
+ columns; the reason is that MySQL may use the
+ clustered index key to store rows, but the mechanism
+ we use below to detect required columns does not
+ reveal that. Actually, it might be enough to
+ fetch only all in the key also in this case! */
templ_type = ROW_MYSQL_WHOLE_ROW;
}
}
if (prebuilt->select_lock_type == LOCK_X) {
- /* TODO: should fix the code in sql_update so that we could do
- with fetching only the needed columns */
+ /* We always retrieve the whole clustered index record if we
+ use exclusive row level locks, for example, if the read is
+ done in an UPDATE statement. */
templ_type = ROW_MYSQL_WHOLE_ROW;
}
if (templ_type == ROW_MYSQL_REC_FIELDS) {
+ /* In versions < 3.23.50 we always retrieved the clustered
+ index record if prebuilt->select_lock_type == LOCK_S,
+ but there is really not need for that, and in some cases
+ performance could be seriously degraded because the MySQL
+ optimizer did not know about our convention! */
- if (prebuilt->select_lock_type != LOCK_NONE) {
- /* Let index be the clustered index */
-
- index = clust_index;
- } else {
- index = prebuilt->index;
- }
+ index = prebuilt->index;
} else {
index = clust_index;
}
@@ -1475,12 +1291,6 @@ skip_field:
(index->table->cols + templ->col_no)->clust_pos;
}
}
-
- if (templ_type == ROW_MYSQL_REC_FIELDS
- && prebuilt->select_lock_type != LOCK_NONE) {
-
- prebuilt->need_to_access_clustered = TRUE;
- }
}
/************************************************************************
@@ -1513,7 +1323,9 @@ ha_innobase::write_row(
}
if (table->next_number_field && record == table->record[0]) {
-
+ /* This is the case where the table has an
+ auto-increment column */
+
/* Fetch the value the user possibly has set in the
autoincrement field */
@@ -1597,12 +1409,6 @@ ha_innobase::write_row(
}
}
- /* Set the 'in_update_remember_pos' flag to FALSE to
- make sure all columns are fetched in the select done by
- update_auto_increment */
-
- prebuilt->in_update_remember_pos = FALSE;
-
update_auto_increment();
if (auto_inc == 0) {
@@ -1626,7 +1432,7 @@ ha_innobase::write_row(
}
/* We have to set sql_stat_start to TRUE because
- update_auto_increment has called a select, and
+ update_auto_increment may have called a select, and
has reset that flag; row_insert_for_mysql has to
know to set the IX intention lock on the table, something
it only does at the start of each statement */
@@ -1866,9 +1672,7 @@ ha_innobase::update_row(
/* This is not a delete */
prebuilt->upd_node->is_delete = FALSE;
- if (!prebuilt->in_update_remember_pos) {
- assert(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
- }
+ assert(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
srv_conc_enter_innodb(prebuilt->trx);
@@ -1914,7 +1718,6 @@ ha_innobase::delete_row(
/* This is a delete */
prebuilt->upd_node->is_delete = TRUE;
- prebuilt->in_update_remember_pos = TRUE;
srv_conc_enter_innodb(prebuilt->trx);
@@ -2124,19 +1927,20 @@ ha_innobase::change_active_index(
active_index = keynr;
- if (keynr != MAX_KEY && table->keys > 0)
- {
+ if (keynr != MAX_KEY && table->keys > 0) {
key = table->key_info + active_index;
- prebuilt->index=dict_table_get_index_noninline(prebuilt->table, key->name);
- if (!prebuilt->index)
- {
- sql_print_error("Innodb could not find key n:o %u with name %s from dict cache for table %s", keynr, key->name, prebuilt->table->name);
- return(1);
- }
+ prebuilt->index = dict_table_get_index_noninline(
+ prebuilt->table, key->name);
+ } else {
+ prebuilt->index = dict_table_get_first_index_noninline(
+ prebuilt->table);
+ }
+
+ if (!prebuilt->index) {
+ sql_print_error("Innodb could not find key n:o %u with name %s from dict cache for table %s", keynr, key->name, prebuilt->table->name);
+ return(1);
}
- else
- prebuilt->index = dict_table_get_first_index_noninline(prebuilt->table);
assert(prebuilt->search_tuple != 0);
@@ -2647,7 +2451,9 @@ ha_innobase::create(
/* Create the table definition in InnoDB */
- if ((error = create_table_def(trx, form, norm_name))) {
+ error = create_table_def(trx, form, norm_name);
+
+ if (error) {
trx_commit_for_mysql(trx);
@@ -3222,11 +3028,57 @@ ha_innobase::update_table_comment(
pos += sprintf(pos, "InnoDB free: %lu kB",
(ulong) innobase_get_free_space());
- /* We assume 150 bytes of space to print info */
+ /* We assume 450 - length bytes of space to print info */
+
+ if (length < 450) {
+ dict_print_info_on_foreign_keys(FALSE, pos, 450 - length,
+ prebuilt->table);
+ }
+
+ return(str);
+}
+
+/***********************************************************************
+Gets the foreign key create info for a table stored in InnoDB. */
+
+char*
+ha_innobase::get_foreign_key_create_info(void)
+/*==========================================*/
+ /* out, own: character string in the form which
+ can be inserted to the CREATE TABLE statement,
+ MUST be freed with ::free_foreign_key_create_info */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
+ char* str;
+
+ if (prebuilt == NULL) {
+ fprintf(stderr,
+"InnoDB: Error: cannot get create info for foreign keys\n");
+
+ return(NULL);
+ }
+
+ str = (char*)ut_malloc(10000);
- dict_print_info_on_foreign_keys(pos, 500, prebuilt->table);
+ str[0] = '\0';
+
+ dict_print_info_on_foreign_keys(TRUE, str, 9000, prebuilt->table);
return(str);
+}
+
+/***********************************************************************
+Frees the foreign key create info for a table stored in InnoDB, if it is
+non-NULL. */
+
+void
+ha_innobase::free_foreign_key_create_info(
+/*======================================*/
+ char* str) /* in, own: create info string to free */
+{
+ if (str) {
+ ut_free(str);
+ }
}
/***********************************************************************
@@ -3254,7 +3106,7 @@ ha_innobase::extra(
prebuilt->read_just_key = 0;
break;
case HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE:
- prebuilt->in_update_remember_pos = FALSE;
+ prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
break;
case HA_EXTRA_KEYREAD:
prebuilt->read_just_key = 1;
@@ -3301,7 +3153,7 @@ ha_innobase::external_lock(
trx = prebuilt->trx;
prebuilt->sql_stat_start = TRUE;
- prebuilt->in_update_remember_pos = TRUE;
+ prebuilt->hint_no_need_to_fetch_extra_cols = TRUE;
prebuilt->read_just_key = 0;
@@ -3320,6 +3172,16 @@ ha_innobase::external_lock(
thd->transaction.all.innodb_active_trans = 1;
trx->n_mysql_tables_in_use++;
+ if (thd->tx_isolation == ISO_SERIALIZABLE
+ && prebuilt->select_lock_type == LOCK_NONE) {
+
+ /* To get serializable execution we let InnoDB
+ conceptually add 'LOCK IN SHARE MODE' to all SELECTs
+ which otherwise would have been consistent reads */
+
+ prebuilt->select_lock_type = LOCK_S;
+ }
+
if (prebuilt->select_lock_type != LOCK_NONE) {
trx->mysql_n_tables_locked++;
@@ -3427,8 +3289,8 @@ ha_innobase::store_lock(
lock_type == TL_READ_NO_INSERT) {
/* This is a SELECT ... IN SHARE MODE, or
we are doing a complex SQL statement like
- INSERT INTO ... SELECT ... and the logical logging
- requires the use of a locking read */
+ INSERT INTO ... SELECT ... and the logical logging (MySQL
+ binlog) requires the use of a locking read */
prebuilt->select_lock_type = LOCK_S;
} else {
@@ -3468,37 +3330,59 @@ ha_innobase::get_auto_increment()
/*=============================*/
/* out: the next auto-increment column value */
{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- longlong nr;
- int error;
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ longlong nr;
+ int error;
- (void) extra(HA_EXTRA_KEYREAD);
- index_init(table->next_number_index);
+ /* Also SHOW TABLE STATUS calls this function. Previously, when we did
+ always read the max autoinc key value, setting x-locks, users were
+ surprised that SHOW TABLE STATUS could end up in a deadlock with
+ ordinary SQL queries. We avoid these deadlocks if the auto-inc
+ counter for the table has been initialized by fetching the value
+ from the table struct in dictionary cache. */
- /* We use an exclusive lock when we read the max key value from the
- auto-increment column index. This is because then build_template will
- advise InnoDB to fetch all columns. In SHOW TABLE STATUS the query
- id of the auto-increment column is not changed, and previously InnoDB
- did not fetch it, causing SHOW TABLE STATUS to show wrong values
- for the autoinc column. */
+ assert(prebuilt->table);
+
+ nr = dict_table_autoinc_read(prebuilt->table);
- prebuilt->select_lock_type = LOCK_X;
- prebuilt->trx->mysql_n_tables_locked += 1;
+ if (nr != 0) {
- error=index_last(table->record[1]);
+ return(nr + 1);
+ }
- if (error) {
- nr = 1;
- } else {
- nr = (longlong) table->next_number_field->
- val_int_offset(table->rec_buff_length) + 1;
- }
+ (void) extra(HA_EXTRA_KEYREAD);
+ index_init(table->next_number_index);
+
+ /* We use an exclusive lock when we read the max key value from the
+ auto-increment column index. This is because then build_template will
+ advise InnoDB to fetch all columns. In SHOW TABLE STATUS the query
+ id of the auto-increment column is not changed, and previously InnoDB
+ did not fetch it, causing SHOW TABLE STATUS to show wrong values
+ for the autoinc column. */
+
+ prebuilt->select_lock_type = LOCK_X;
+
+ /* Play safe and also give in another way the hint to fetch
+ all columns in the key: */
+
+ prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
+
+ prebuilt->trx->mysql_n_tables_locked += 1;
+
+ error = index_last(table->record[1]);
+
+ if (error) {
+ nr = 1;
+ } else {
+ nr = (longlong) table->next_number_field->
+ val_int_offset(table->rec_buff_length) + 1;
+ }
- (void) extra(HA_EXTRA_NO_KEYREAD);
+ (void) extra(HA_EXTRA_NO_KEYREAD);
- index_end();
+ index_end();
- return(nr);
+ return(nr);
}
#endif /* HAVE_INNOBASE_DB */
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
index faae42575b5..a0f3ea28d2c 100644
--- a/sql/ha_innodb.h
+++ b/sql/ha_innodb.h
@@ -158,7 +158,8 @@ class ha_innobase: public handler
int rename_table(const char* from, const char* to);
int check(THD* thd, HA_CHECK_OPT* check_opt);
char* update_table_comment(const char* comment);
-
+ char* get_foreign_key_create_info();
+ void free_foreign_key_create_info(char* str);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type);
longlong get_auto_increment();
diff --git a/sql/handler.cc b/sql/handler.cc
index e0e9ee25506..3e951efff48 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -225,13 +225,13 @@ int ha_autocommit_or_rollback(THD *thd, int error)
/*
This function is called when MySQL writes the log segment of a
transaction to the binlog. It is called when the LOCK_log mutex is
- reserved. Here we communicate to transactional table handlers whta
+ reserved. Here we communicate to transactional table handlers what
binlog position corresponds to the current transaction. The handler
can store it and in recovery print to the user, so that the user
knows from what position in the binlog to start possible
roll-forward, for example, if the crashed server was a slave in
replication. This function also calls the commit of the table
- handler, because the order of trasnactions in the log of the table
+ handler, because the order of transactions in the log of the table
handler must be the same as in the binlog.
arguments:
@@ -263,7 +263,6 @@ int ha_report_binlog_offset_and_commit(THD *thd,
return error;
}
-
int ha_commit_trans(THD *thd, THD_TRANS* trans)
{
int error=0;
diff --git a/sql/handler.h b/sql/handler.h
index fd59dabce3e..868badf4d49 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -308,7 +308,9 @@ public:
virtual char *update_table_comment(const char * comment)
{ return (char*) comment;}
virtual void append_create_info(String *packet) {}
-
+ virtual char* get_foreign_key_create_info()
+ { return(NULL);} /* gets foreign key create string from InnoDB */
+ virtual void free_foreign_key_create_info(char* str) {}
/* The following can be called without an open handler */
virtual const char *table_type() const =0;
virtual const char **bas_ext() const =0;
diff --git a/sql/item.cc b/sql/item.cc
index c081fd9dd5f..dac10eafafb 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -59,12 +59,28 @@ void Item::set_name(char *str,uint length)
}
}
-bool Item::eq(const Item *item) const // Only doing this on conds
+/*
+ This function is only called when comparing items in the WHERE clause
+*/
+
+bool Item::eq(const Item *item, bool binary_cmp) const
{
return type() == item->type() && name && item->name &&
!my_strcasecmp(name,item->name);
}
+bool Item_string::eq(const Item *item, bool binary_cmp) const
+{
+ if (type() == item->type())
+ {
+ if (binary_cmp)
+ return !stringcmp(&str_value, &item->str_value);
+ return !sortcmp(&str_value, &item->str_value);
+ }
+ return 0;
+}
+
+
/*
Get the value of the function as a TIME structure.
As a extra convenience the time structure is reset on error!
@@ -203,7 +219,7 @@ longlong Item_field::val_int_result()
return result_field->val_int();
}
-bool Item_field::eq(const Item *item) const
+bool Item_field::eq(const Item *item, bool binary_cmp) const
{
return item->type() == FIELD_ITEM && ((Item_field*) item)->field == field;
}
@@ -262,7 +278,8 @@ void Item_string::print(String *str)
str->append('\'');
}
-bool Item_null::eq(const Item *item) const { return item->type() == type(); }
+bool Item_null::eq(const Item *item, bool binary_cmp) const
+{ return item->type() == type(); }
double Item_null::val() { null_value=1; return 0.0; }
longlong Item_null::val_int() { null_value=1; return 0; }
/* ARGSUSED */
diff --git a/sql/item.h b/sql/item.h
index 660a36ee967..575af197e7d 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -57,7 +57,7 @@ public:
virtual void save_org_in_field(Field *field)
{ (void) save_in_field(field); }
virtual bool send(THD *thd, String *str);
- virtual bool eq(const Item *) const;
+ virtual bool eq(const Item *, bool binary_cmp) const;
virtual Item_result result_type () const { return REAL_RESULT; }
virtual enum Type type() const =0;
virtual double val()=0;
@@ -111,7 +111,7 @@ public:
{}
Item_field(Field *field);
enum Type type() const { return FIELD_ITEM; }
- bool eq(const Item *item) const;
+ bool eq(const Item *item, bool binary_cmp) const;
double val();
longlong val_int();
String *val_str(String*);
@@ -141,7 +141,7 @@ public:
Item_null(char *name_par=0)
{ maybe_null=null_value=TRUE; name= name_par ? name_par : (char*) "NULL";}
enum Type type() const { return NULL_ITEM; }
- bool eq(const Item *item) const;
+ bool eq(const Item *item, bool binary_cmp) const;
double val();
longlong val_int();
String *val_str(String *str);
@@ -264,6 +264,7 @@ public:
void make_field(Send_field *field);
enum Item_result result_type () const { return STRING_RESULT; }
bool basic_const_item() const { return 1; }
+ bool eq(const Item *item, bool binary_cmp) const;
Item *new_item() { return new Item_string(name,str_value.ptr(),max_length); }
String *const_string() { return &str_value; }
inline void append(char *str,uint length) { str_value.append(str,length); }
@@ -323,7 +324,8 @@ public:
Item_ref(Item **item, char *table_name_par,char *field_name_par)
:Item_ident(NullS,table_name_par,field_name_par),ref(item) {}
enum Type type() const { return REF_ITEM; }
- bool eq(const Item *item) const { return (*ref)->eq(item); }
+ bool eq(const Item *item, bool binary_cmp) const
+ { return (*ref)->eq(item, binary_cmp); }
~Item_ref() { if (ref) delete *ref; }
double val()
{
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 01b3e4e89c4..e643075b0bc 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -148,7 +148,7 @@ void Item_func::print_op(String *str)
str->append(')');
}
-bool Item_func::eq(const Item *item) const
+bool Item_func::eq(const Item *item, bool binary_cmp) const
{
/* Assume we don't have rtti */
if (this == item)
@@ -160,7 +160,7 @@ bool Item_func::eq(const Item *item) const
func_name() != item_func->func_name())
return 0;
for (uint i=0; i < arg_count ; i++)
- if (!args[i]->eq(item_func->args[i]))
+ if (!args[i]->eq(item_func->args[i], binary_cmp))
return 0;
return 1;
}
@@ -1975,7 +1975,7 @@ void Item_func_get_user_var::print(String *str)
str->append(')');
}
-bool Item_func_get_user_var::eq(const Item *item) const
+bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const
{
/* Assume we don't have rtti */
if (this == item)
@@ -2198,7 +2198,7 @@ err:
return 1;
}
-bool Item_func_match::eq(const Item *item) const
+bool Item_func_match::eq(const Item *item, bool binary_cmp) const
{
if (item->type() != FUNC_ITEM)
return 0;
@@ -2209,7 +2209,7 @@ bool Item_func_match::eq(const Item *item) const
Item_func_match *ifm=(Item_func_match*) item;
if (key == ifm->key && table == ifm->table &&
- key_item()->eq(ifm->key_item()))
+ key_item()->eq(ifm->key_item(), binary_cmp))
return 1;
return 0;
diff --git a/sql/item_func.h b/sql/item_func.h
index 3ef50340d98..c3e437712ee 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -98,7 +98,7 @@ public:
void make_field(Send_field *field);
table_map used_tables() const;
void update_used_tables();
- bool eq(const Item *item) const;
+ bool eq(const Item *item, bool binary_cmp) const;
virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; }
virtual bool have_rev_func() const { return 0; }
virtual Item *key_item() const { return args[0]; }
@@ -889,7 +889,7 @@ public:
bool const_item() const { return const_var_flag; }
table_map used_tables() const
{ return const_var_flag ? 0 : RAND_TABLE_BIT; }
- bool eq(const Item *item) const;
+ bool eq(const Item *item, bool binary_cmp) const;
};
@@ -937,7 +937,7 @@ public:
enum Functype functype() const { return FT_FUNC; }
void update_used_tables() {}
bool fix_fields(THD *thd,struct st_table_list *tlist);
- bool eq(const Item *) const;
+ bool eq(const Item *, bool binary_cmp) const;
longlong val_int() { return val()!=0.0; }
double val();
diff --git a/sql/lock.cc b/sql/lock.cc
index 5d2856278b6..db849757741 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -88,6 +88,13 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
thd->locked=0;
break;
}
+ else if (!thd->open_tables)
+ {
+ // Only using temporary tables, no need to unlock
+ thd->some_tables_deleted=0;
+ thd->locked=0;
+ break;
+ }
/* some table was altered or deleted. reopen tables marked deleted */
mysql_unlock_tables(thd,sql_lock);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index fa3a8f118b1..8f0440ecc04 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -162,6 +162,7 @@ static SECURITY_DESCRIPTOR sdPipeDescriptor;
static HANDLE hPipe = INVALID_HANDLE_VALUE;
static pthread_cond_t COND_handler_count;
static uint handler_count;
+static bool opt_enable_named_pipe = 0;
#endif
#ifdef __WIN__
static bool opt_console=0,start_mode=0;
@@ -482,7 +483,7 @@ static void close_connections(void)
}
}
#ifdef __NT__
- if ( hPipe != INVALID_HANDLE_VALUE )
+ if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
{
HANDLE temp;
DBUG_PRINT( "quit", ("Closing named pipes") );
@@ -983,7 +984,8 @@ static void server_init(void)
#ifdef __NT__
/* create named pipe */
- if (Service.IsNT() && mysql_unix_port[0] && !opt_bootstrap)
+ if (Service.IsNT() && mysql_unix_port[0] && !opt_bootstrap &&
+ opt_enable_named_pipe)
{
sprintf( szPipeName, "\\\\.\\pipe\\%s", mysql_unix_port );
ZeroMemory( &saPipeSecurity, sizeof(saPipeSecurity) );
@@ -1722,7 +1724,7 @@ int main(int argc, char **argv)
if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0)
strmov(glob_hostname,"mysql");
- strmov(pidfile_name,glob_hostname);
+ strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
strmov(strcend(pidfile_name,'.'),".pid"); // Add extension
#ifndef DBUG_OFF
strxmov(strend(server_version),MYSQL_SERVER_SUFFIX,"-debug",NullS);
@@ -2043,9 +2045,11 @@ The server will not act as a slave.");
fflush(stdout);
#ifdef __NT__
- if (hPipe == INVALID_HANDLE_VALUE && !have_tcpip)
+ if (hPipe == INVALID_HANDLE_VALUE &&
+ (!have_tcpip || opt_disable_networking)
{
- sql_print_error("TCP/IP or Named Pipes should be installed on NT OS");
+ sql_print_error("TCP/IP or --enable-named-pipe should be configured on NT OS");
+ unireg_abort(1);
}
else
{
@@ -2054,7 +2058,7 @@ The server will not act as a slave.");
{
pthread_t hThread;
handler_count=0;
- if ( hPipe != INVALID_HANDLE_VALUE )
+ if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
{
handler_count++;
if (pthread_create(&hThread,&connection_attrib,
@@ -2571,9 +2575,9 @@ pthread_handler_decl(handle_connections_namedpipes,arg)
fConnected = ConnectNamedPipe( hPipe, NULL );
if (abort_loop)
break;
- if ( !fConnected )
+ if (!fConnected)
fConnected = GetLastError() == ERROR_PIPE_CONNECTED;
- if ( !fConnected )
+ if (!fConnected)
{
CloseHandle( hPipe );
if ((hPipe = CreateNamedPipe(szPipeName,
@@ -2611,7 +2615,7 @@ pthread_handler_decl(handle_connections_namedpipes,arg)
continue; // We have to try again
}
- if ( !(thd = new THD))
+ if (!(thd = new THD))
{
DisconnectNamedPipe( hConnectedPipe );
CloseHandle( hConnectedPipe );
@@ -2695,6 +2699,7 @@ enum options {
OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
OPT_SAFE_USER_CREATE, OPT_SQL_MODE,
+ OPT_HAVE_NAMED_PIPE,
OPT_DO_PSTACK, OPT_REPORT_HOST,
OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT,
OPT_SHOW_SLAVE_AUTH_INFO, OPT_OLD_RPL_COMPAT,
@@ -2735,6 +2740,7 @@ static struct option long_options[] = {
{"delay-key-write-for-all-tables",
no_argument, 0, (int) OPT_DELAY_KEY_WRITE},
{"enable-locking", no_argument, 0, (int) OPT_ENABLE_LOCK},
+ {"enable-named-pipe", no_argument, 0, (int) OPT_HAVE_NAMED_PIPE},
{"enable-pstack", no_argument, 0, (int) OPT_DO_PSTACK},
{"exit-info", optional_argument, 0, 'T'},
{"flush", no_argument, 0, (int) OPT_FLUSH},
@@ -3119,6 +3125,9 @@ struct show_var_st init_vars[]= {
{"myisam_max_sort_file_size",(char*) &myisam_max_sort_file_size, SHOW_LONG},
{"myisam_recover_options", (char*) &myisam_recover_options_str, SHOW_CHAR_PTR},
{"myisam_sort_buffer_size", (char*) &myisam_sort_buffer_size, SHOW_LONG},
+#ifdef __NT__
+ {"named_pipe", (char*) &opt_enable_named_pipe, SHOW_BOOL},
+#endif
{"net_buffer_length", (char*) &net_buffer_length, SHOW_LONG},
{"net_read_timeout", (char*) &net_read_timeout, SHOW_LONG},
{"net_retry_count", (char*) &mysqld_net_retry_count, SHOW_LONG},
@@ -3453,10 +3462,12 @@ Starts the MySQL server\n");
-W, --warnings Log some not critical warnings to the log file\n");
#ifdef __WIN__
puts("NT and Win32 specific options:\n\
- --console Don't remove the console window\n\
- --install Install mysqld as a service (NT)\n\
- --remove Remove mysqld from the service list (NT)\n\
- --standalone Dummy option to start as a standalone program (NT)\
+ --console Don't remove the console window\n\
+ --install Install the default service (NT)\n\
+ --install-manual Install the default service started manually (NT)\n\
+ --remove Remove the default service from the service list (NT)\n\
+ --enable-named-pipe Enable the named pipe (NT)\n\
+ --standalone Dummy option to start as a standalone program (NT)\
");
#ifdef USE_SYMDIR
puts("--use-symbolic-links Enable symbolic link support");
@@ -3543,9 +3554,10 @@ static void set_options(void)
opt_specialflag |= SPECIAL_NO_PRIOR;
#endif
- (void) strmov( default_charset, MYSQL_CHARSET);
- (void) strmov( language, LANGUAGE);
- (void) strmov( mysql_real_data_home, get_relative_path(DATADIR));
+ (void) strmake(default_charset, MYSQL_CHARSET, sizeof(default_charset)-1);
+ (void) strmake(language, LANGUAGE, sizeof(language)-1);
+ (void) strmake(mysql_real_data_home, get_relative_path(DATADIR),
+ sizeof(mysql_real_data_home-1));
#ifdef __WIN__
/* Allow Win32 users to move MySQL anywhere */
{
@@ -3556,9 +3568,9 @@ static void set_options(void)
}
#else
const char *tmpenv;
- if ( !(tmpenv = getenv("MY_BASEDIR_VERSION")))
+ if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
tmpenv = DEFAULT_MYSQL_HOME;
- (void) strmov( mysql_home, tmpenv );
+ (void) strmake(mysql_home, tmpenv, sizeof(mysql_home)-1);
#endif
#if defined( HAVE_mit_thread ) || defined( __WIN__ ) || defined( HAVE_LINUXTHREADS )
@@ -3604,17 +3616,17 @@ static void get_options(int argc,char **argv)
default_tx_isolation= ISO_SERIALIZABLE;
break;
case 'b':
- strmov(mysql_home,optarg);
+ strmake(mysql_home,optarg,sizeof(mysql_home)-1);
break;
case 'l':
opt_log=1;
opt_logname=optarg; // Use hostname.log if null
break;
case 'h':
- strmov(mysql_real_data_home,optarg);
+ strmake(mysql_real_data_home,optarg, sizeof(mysql_real_data_home)-1);
break;
case 'L':
- strmov(language,optarg);
+ strmake(language, optarg, sizeof(language)-1);
break;
case 'n':
opt_specialflag|= SPECIAL_NEW_FUNC;
@@ -3972,11 +3984,16 @@ static void get_options(int argc,char **argv)
}
break;
case (int) OPT_PID_FILE:
- strmov(pidfile_name,optarg);
+ strmake(pidfile_name, optarg, sizeof(pidfile_name)-1);
break;
case (int) OPT_INIT_FILE:
opt_init_file=optarg;
break;
+ case (int) OPT_HAVE_NAMED_PIPE:
+#if __NT__
+ opt_enable_named_pipe=1;
+#endif
+ break;
#ifdef __WIN__
case (int) OPT_STANDALONE: /* Dummy option for NT */
break;
@@ -4022,10 +4039,10 @@ static void get_options(int argc,char **argv)
myisam_delay_key_write=0;
break;
case 'C':
- strmov(default_charset,optarg);
+ strmake(default_charset, optarg, sizeof(default_charset)-1);
break;
case OPT_CHARSETS_DIR:
- strmov(mysql_charsets_dir, optarg);
+ strmake(mysql_charsets_dir, optarg, sizeof(mysql_charsets_dir)-1);
charsets_dir = mysql_charsets_dir;
break;
#include "sslopt-case.h"
@@ -4295,16 +4312,17 @@ static void fix_paths(void)
char buff[FN_REFLEN],*sharedir=get_relative_path(SHAREDIR);
if (test_if_hard_path(sharedir))
- strmov(buff,sharedir); /* purecov: tested */
+ strmake(buff,sharedir,sizeof(buff)-1); /* purecov: tested */
else
- strxmov(buff,mysql_home,sharedir,NullS);
+ strxnmov(buff,sizeof(buff)-1,mysql_home,sharedir,NullS);
convert_dirname(buff,buff,NullS);
(void) my_load_path(language,language,buff);
/* If --character-sets-dir isn't given, use shared library dir */
if (charsets_dir != mysql_charsets_dir)
{
- strmov(strmov(mysql_charsets_dir,buff),CHARSET_DIR);
+ strxnmov(mysql_charsets_dir, sizeof(mysql_charsets_dir)-1, buff,
+ CHARSET_DIR, NullS);
charsets_dir=mysql_charsets_dir;
}
diff --git a/sql/share/Makefile.am b/sql/share/Makefile.am
index cb3056b5f5a..c70ac9ccf57 100644
--- a/sql/share/Makefile.am
+++ b/sql/share/Makefile.am
@@ -5,6 +5,7 @@ dist-hook:
test -d $(distdir)/$$dir || mkdir $(distdir)/$$dir; \
$(INSTALL_DATA) $(srcdir)/$$dir/*.* $(distdir)/$$dir; \
done; \
+ sleep 1 ; touch $(srcdir)/*/errmsg.sys
$(INSTALL_DATA) $(srcdir)/charsets/README $(distdir)/charsets
$(INSTALL_DATA) $(srcdir)/charsets/Index $(distdir)/charsets
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 5d80fd63d13..88854396ae3 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -430,6 +430,7 @@ void close_thread_tables(THD *thd, bool locked)
while (thd->open_tables)
found_old_table|=close_thread_table(thd, &thd->open_tables);
+ thd->some_tables_deleted=0;
/* Free tables to hold down open files */
while (open_cache.records > table_cache_size && unused_tables)
@@ -1692,7 +1693,7 @@ find_item_in_list(Item *find,List<Item> &items)
{
if (found)
{
- if ((*found)->eq(item))
+ if ((*found)->eq(item,0))
continue; // Same field twice (Access?)
if (current_thd->where)
my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0),
@@ -1708,7 +1709,7 @@ find_item_in_list(Item *find,List<Item> &items)
}
}
}
- else if (!table_name && (item->eq(find) ||
+ else if (!table_name && (item->eq(find,0) ||
find->name &&
!my_strcasecmp(item->name,find->name)))
{
@@ -2186,7 +2187,7 @@ int setup_ftfuncs(THD *thd)
lj.rewind();
while ((ftf2=lj++) != ftf)
{
- if (ftf->eq(ftf2) && !ftf2->master)
+ if (ftf->eq(ftf2,1) && !ftf2->master)
ftf2->master=ftf;
}
}
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index f2a0351361b..305491c7346 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -126,7 +126,7 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
new_table=ren_table->next;
sprintf(name,"%s/%s/%s%s",mysql_data_home,
- new_table->db,new_table->name,
+ new_table->db,new_table->real_name,
reg_ext);
if (!access(name,F_OK))
{
@@ -134,7 +134,7 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
DBUG_RETURN(ren_table); // This can't be skipped
}
sprintf(name,"%s/%s/%s%s",mysql_data_home,
- ren_table->db,ren_table->name,
+ ren_table->db,ren_table->real_name,
reg_ext);
if ((table_type=get_table_type(name)) == DB_TYPE_UNKNOWN)
{
@@ -143,11 +143,11 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
DBUG_RETURN(ren_table);
}
else if (mysql_rename_table(table_type,
- ren_table->db, ren_table->name,
- new_table->db, new_table->name))
+ ren_table->db, ren_table->real_name,
+ new_table->db, new_table->real_name))
{
if (!skip_error)
- return ren_table;
+ DBUG_RETURN(ren_table);
}
}
DBUG_RETURN(0);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 8e2ef3993ea..82fe4d0c723 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1247,14 +1247,14 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
{
if (new_fields->val->used_tables())
{
- if (old->val->eq(new_fields->val))
+ if (old->val->eq(new_fields->val, old->field->binary()))
{
old->level=old->const_level=and_level;
old->exists_optimize&=new_fields->exists_optimize;
}
}
- else if (old->val->eq(new_fields->val) && old->eq_func &&
- new_fields->eq_func)
+ else if (old->val->eq(new_fields->val, old->field->binary()) &&
+ old->eq_func && new_fields->eq_func)
{
old->level=old->const_level=and_level;
old->exists_optimize&=new_fields->exists_optimize;
@@ -2769,7 +2769,7 @@ eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab)
ORDER *order;
for (order=start_order ; order ; order=order->next)
{
- if ((*ref_item)->eq(order->item[0]))
+ if ((*ref_item)->eq(order->item[0],0))
break;
}
if (order)
@@ -3026,7 +3026,7 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father,
Item *right_item= func->arguments()[1];
Item_func::Functype functype= func->functype();
- if (right_item->eq(field) && left_item != value)
+ if (right_item->eq(field,0) && left_item != value)
{
Item *tmp=value->new_item();
if (tmp)
@@ -3045,7 +3045,7 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father,
func->arguments()[1]->result_type()));
}
}
- else if (left_item->eq(field) && right_item != value)
+ else if (left_item->eq(field,0) && right_item != value)
{
Item *tmp=value->new_item();
if (tmp)
@@ -3286,7 +3286,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
{ // boolan compare function
Item *left_item= ((Item_func*) cond)->arguments()[0];
Item *right_item= ((Item_func*) cond)->arguments()[1];
- if (left_item->eq(right_item))
+ if (left_item->eq(right_item,1))
{
if (!left_item->maybe_null ||
((Item_func*) cond)->functype() == Item_func::EQUAL_FUNC)
@@ -3331,22 +3331,22 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
return 0;
Item *left_item= ((Item_func*) cond)->arguments()[0];
Item *right_item= ((Item_func*) cond)->arguments()[1];
- if (left_item->eq(comp_item))
+ if (left_item->eq(comp_item,1))
{
if (right_item->const_item())
{
if (*const_item)
- return right_item->eq(*const_item);
+ return right_item->eq(*const_item, 1);
*const_item=right_item;
return 1;
}
}
- else if (right_item->eq(comp_item))
+ else if (right_item->eq(comp_item,1))
{
if (left_item->const_item())
{
if (*const_item)
- return left_item->eq(*const_item);
+ return left_item->eq(*const_item, 1);
*const_item=left_item;
return 1;
}
@@ -5267,7 +5267,7 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
if (!field->table->const_table && !field->table->maybe_null)
{
Item *ref_item=part_of_refkey(field->table,field);
- if (ref_item && ref_item->eq(right_item))
+ if (ref_item && ref_item->eq(right_item,1))
{
if (right_item->type() == Item::FIELD_ITEM)
return (field->eq_def(((Item_field *) right_item)->field));
@@ -6513,7 +6513,7 @@ test_if_subpart(ORDER *a,ORDER *b)
{
for (; a && b; a=a->next,b=b->next)
{
- if ((*a->item)->eq(*b->item))
+ if ((*a->item)->eq(*b->item,1))
a->asc=b->asc;
else
return 0;
@@ -6540,7 +6540,7 @@ get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables)
for (; a && b; a=a->next,b=b->next)
{
- if (!(*a->item)->eq(*b->item))
+ if (!(*a->item)->eq(*b->item,1))
DBUG_RETURN(0);
map|=a->item[0]->used_tables();
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 131266a11d6..08c17c2e25d 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -908,9 +908,21 @@ store_create_info(THD *thd, TABLE *table, String *packet)
}
packet->append(')');
}
- packet->append("\n)", 2);
handler *file = table->file;
+
+ /* Get possible foreign key definitions stored in InnoDB and append them
+ to the CREATE TABLE statement */
+
+ char* for_str = file->get_foreign_key_create_info();
+
+ if (for_str) {
+ packet->append(for_str, strlen(for_str));
+
+ file->free_foreign_key_create_info(for_str);
+ }
+
+ packet->append("\n)", 2);
packet->append(" TYPE=", 6);
packet->append(file->table_type());
char buff[128];