summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <serg@serg.mysql.com>2002-04-02 14:59:40 +0000
committerunknown <serg@serg.mysql.com>2002-04-02 14:59:40 +0000
commitd2771b82a48ae4a0548daffba5961c5b345f019c (patch)
treeffe29ba0f45879ed83f8af080165d5ef573d7534 /sql
parent8bf63614de3e2f09559a952f9f2ad9b7af4ef794 (diff)
parentb344dbc2da2811e6c31274c3aa3b3df56fa0bdf6 (diff)
downloadmariadb-git-d2771b82a48ae4a0548daffba5961c5b345f019c.tar.gz
Merge work:/home/bk/mysql into serg.mysql.com:/usr/home/serg/Abk/mysql
sql/item_func.cc: Auto merged sql/item_func.h: Auto merged sql/mysqld.cc: Auto merged sql/sql_select.cc: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/convert.cc2
-rw-r--r--sql/ha_innobase.cc500
-rw-r--r--sql/ha_innobase.h3
-rw-r--r--sql/ha_isam.cc2
-rw-r--r--sql/ha_myisam.cc2
-rw-r--r--sql/ha_myisammrg.cc2
-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/item_timefunc.cc2
-rw-r--r--sql/item_timefunc.h1
-rw-r--r--sql/lock.cc7
-rw-r--r--sql/log_event.h5
-rw-r--r--sql/mysqld.cc75
-rw-r--r--sql/share/Makefile.am1
-rw-r--r--sql/sql_acl.cc22
-rw-r--r--sql/sql_base.cc8
-rw-r--r--sql/sql_load.cc5
-rw-r--r--sql/sql_rename.cc10
-rw-r--r--sql/sql_select.cc28
-rw-r--r--sql/sql_show.cc14
-rw-r--r--sql/sql_yacc.yy2
-rw-r--r--sql/table.cc6
26 files changed, 352 insertions, 403 deletions
diff --git a/sql/convert.cc b/sql/convert.cc
index 3e0fbf18ace..2c8b775dca2 100644
--- a/sql/convert.cc
+++ b/sql/convert.cc
@@ -456,7 +456,7 @@ bool CONVERT::store(String *packet,const char *from,uint length)
packet->realloc(packet_length+5+length))
return 1;
char *to=(char*) net_store_length((char*) packet->ptr()+packet_length,
- length);
+ (ulonglong)length);
for (const char *end=from+length ; from != end ; from++)
*to++= to_map[(uchar) *from];
diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc
index 2cdf15ce974..9159ef3f1c1 100644
--- a/sql/ha_innobase.cc
+++ b/sql/ha_innobase.cc
@@ -76,20 +76,34 @@ 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;
+ innobase_thread_concurrency, innobase_force_recovery;
-char *innobase_data_home_dir, *innobase_data_file_path;
-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;
+/* 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_data_file_path = 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;
+
/* The following counter is used to convey information to InnoDB
about server activity: in selects it is not sensible to call
srv_active_wake_master_thread after each fetch or search, we only do
@@ -332,227 +346,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 = 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 = 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
@@ -565,7 +358,7 @@ innobase_init(void)
bool ret;
DBUG_ENTER("innobase_init");
-
+
if (specialflag & SPECIAL_NO_PRIOR) {
srv_set_thread_priorities = FALSE;
} else {
@@ -574,49 +367,62 @@ innobase_init(void)
}
/* Use current_dir if no paths are set */
- current_dir[0]=FN_CURLIB;
- current_dir[1]=FN_LIBCHAR;
- current_dir[2]=0;
+ current_dir[0] = FN_CURLIB;
+ current_dir[1] = FN_LIBCHAR;
+ current_dir[2] = 0;
/* Set InnoDB initialization parameters according to the values
read from MySQL .cnf file */
- if (!innobase_data_file_path)
- {
- fprintf(stderr,
+ if (!innobase_data_file_path) {
+ fprintf(stderr,
"Cannot initialize InnoDB as 'innodb_data_file_path' is not set.\n"
"If you do not want to use transactional InnoDB tables, add a line\n"
"skip-innodb\n"
"to the [mysqld] section of init parameters in your my.cnf\n"
"or my.ini. If you want to use InnoDB tables, add for example,\n"
- "innodb_data_file_path = ibdata1:30M\n"
+ "innodb_data_file_path = ibdata1:30M:autoextend\n"
"But to get good performance you should adjust for your hardware\n"
"the InnoDB startup options listed in section 2 at\n"
"http://www.innodb.com/ibman.html\n");
- innodb_skip=1;
- DBUG_RETURN(FALSE); // Continue without innobase
+ innodb_skip=1;
+ DBUG_RETURN(FALSE); /* Continue without InnoDB */
}
srv_data_home = (innobase_data_home_dir ? innobase_data_home_dir :
current_dir);
- srv_logs_home = (char*) "";
srv_arch_dir = (innobase_log_arch_dir ? innobase_log_arch_dir :
current_dir);
- 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) {
- fprintf(stderr, "InnoDB: syntax error in innodb_data_file_path\n");
- DBUG_RETURN(TRUE);
+ fprintf(stderr,
+ "InnoDB: syntax error in innodb_data_file_path\n");
+ DBUG_RETURN(TRUE);
+ }
+
+ if (!innobase_log_group_home_dir) {
+ innobase_log_group_home_dir = current_dir;
}
- if (!innobase_log_group_home_dir)
- innobase_log_group_home_dir= current_dir;
- ret = innobase_parse_log_group_home_dirs();
+ ret = (bool)
+ srv_parse_log_group_home_dirs(innobase_log_group_home_dir,
+ &srv_log_group_home_dirs);
- if (ret == FALSE) {
- DBUG_RETURN(TRUE);
+ 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 ?
@@ -658,10 +464,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);
}
@@ -1340,33 +1147,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;
}
@@ -1462,12 +1279,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;
- }
}
/************************************************************************
@@ -1500,7 +1311,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 */
@@ -1584,12 +1397,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) {
@@ -1613,7 +1420,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 */
@@ -1853,9 +1660,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);
@@ -1901,7 +1706,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);
@@ -2616,7 +2420,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);
@@ -3203,14 +3009,60 @@ 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 */
- dict_print_info_on_foreign_keys(pos, 500, prebuilt->table);
+ 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);
+
+ 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);
+ }
+}
+
+/***********************************************************************
Tells something additional to the handler about how to do things. */
int
@@ -3235,7 +3087,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;
@@ -3282,7 +3134,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;
@@ -3301,6 +3153,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++;
@@ -3407,8 +3269,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 {
@@ -3448,37 +3310,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;
+
+ /* 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. */
+
+ assert(prebuilt->table);
+
+ nr = dict_table_autoinc_read(prebuilt->table);
+
+ if (nr != 0) {
+
+ return(nr + 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. */
- (void) extra(HA_EXTRA_KEYREAD);
- index_init(table->next_number_index);
+ prebuilt->select_lock_type = LOCK_X;
- /* 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. */
+ /* 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->select_lock_type = LOCK_X;
- prebuilt->trx->mysql_n_tables_locked += 1;
+ prebuilt->trx->mysql_n_tables_locked += 1;
- error=index_last(table->record[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;
- }
+ 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_innobase.h b/sql/ha_innobase.h
index ec77cd1a70f..9f752dd2eda 100644
--- a/sql/ha_innobase.h
+++ b/sql/ha_innobase.h
@@ -154,7 +154,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/ha_isam.cc b/sql/ha_isam.cc
index 746fdd2f585..ac37d09e6b4 100644
--- a/sql/ha_isam.cc
+++ b/sql/ha_isam.cc
@@ -191,7 +191,7 @@ void ha_isam::info(uint flag)
sortkey = info.sortkey;
block_size=nisam_block_size;
table->keys = min(table->keys,info.keys);
- table->keys_in_use= (((key_map) 1) << table->keys)- (key_map) 1;
+ table->keys_in_use= set_bits(key_map,table->keys);
table->db_options_in_use= info.options;
table->db_record_offset=
(table->db_options_in_use &
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index fb98708c317..595c83ff8ef 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -664,7 +664,7 @@ bool ha_myisam::activate_all_index(THD *thd)
MI_CHECK param;
MYISAM_SHARE* share = file->s;
DBUG_ENTER("activate_all_index");
- if (share->state.key_map != ((ulonglong) 1L << share->base.keys)-1)
+ if (share->state.key_map != set_bits(ulonglong, share->base.keys))
{
const char *save_proc_info=thd->proc_info;
thd->proc_info="Creating index";
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index 9499c42fdc9..e5fb0310a36 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -169,7 +169,7 @@ void ha_myisammrg::info(uint flag)
deleted = (ha_rows) info.deleted;
data_file_length=info.data_file_length;
errkey = info.errkey;
- table->keys_in_use=(((key_map) 1) << table->keys)- (key_map) 1;
+ table->keys_in_use= set_bits(key_map, table->keys);
table->db_options_in_use = info.options;
table->is_view=1;
mean_rec_length=info.reclength;
diff --git a/sql/handler.cc b/sql/handler.cc
index 5a713bccc1e..098c3130de2 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -260,13 +260,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:
@@ -298,7 +298,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 e4cac60ed67..89c19993238 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -294,7 +294,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 b268c5eb928..0ce37cdd593 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!
@@ -202,7 +218,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;
}
@@ -245,7 +261,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 c868f9d3bf7..41b897956db 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -56,7 +56,7 @@ public:
virtual void save_org_in_field(Field *field)
{ (void) save_in_field(field); }
virtual bool send(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;
@@ -109,7 +109,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*);
@@ -138,7 +138,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);
@@ -247,6 +247,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); }
@@ -306,7 +307,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 ec9244e783e..023b79b3ff7 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;
}
@@ -1882,7 +1882,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)
@@ -2136,7 +2136,7 @@ bool Item_func_match::fix_index()
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;
@@ -2147,7 +2147,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 c0924ba0289..1d85973055b 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]; }
@@ -842,7 +842,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;
};
@@ -888,7 +888,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;
double val();
longlong val_int() { return val()!=0.0; }
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index b198900d24e..eb9b1423c78 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -672,7 +672,7 @@ String *Item_func_date_format::val_str(String *str)
else
size=format_length(format);
if (format == str)
- str=&str_value; // Save result here
+ str=&value; // Save result here
if (str->alloc(size))
{
null_value=1;
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 1343cdad390..6913d4c6809 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -297,6 +297,7 @@ class Item_func_date_format :public Item_str_func
{
int fixed_length;
const bool date_or_time;
+ String value;
public:
Item_func_date_format(Item *a,Item *b,bool date_or_time_arg)
:Item_str_func(a,b),date_or_time(date_or_time_arg) {}
diff --git a/sql/lock.cc b/sql/lock.cc
index aa06822e03f..a9054b99186 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -108,6 +108,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/log_event.h b/sql/log_event.h
index 94f7cce0e35..a31c698fae9 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -229,12 +229,13 @@ public:
THD* thd;
String field_lens_buf;
String fields_buf;
- Load_log_event(THD* thd, sql_exchange* ex, const char* table_name_arg,
+ Load_log_event(THD* thd, sql_exchange* ex,
+ const char *db_arg, const char* table_name_arg,
List<Item>& fields_arg, enum enum_duplicates handle_dup ):
Log_event(thd->start_time),data_buf(0),thread_id(thd->thread_id),
num_fields(0),fields(0),field_lens(0),field_block_len(0),
table_name(table_name_arg),
- db(thd->db),
+ db(db_arg),
fname(ex->file_name),
thd(thd)
{
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 6011ad210f0..1d108b3f4c2 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -160,6 +160,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;
@@ -474,7 +475,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") );
@@ -928,7 +929,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) );
@@ -1662,7 +1664,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);
@@ -2005,9 +2007,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
{
@@ -2016,7 +2020,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,
@@ -2509,9 +2513,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,
@@ -2549,7 +2553,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 );
@@ -2633,6 +2637,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_SLAVE_SKIP_ERRORS, OPT_LOCAL_INFILE
};
@@ -2666,6 +2671,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},
{"exit-info", optional_argument, 0, 'T'},
{"flush", no_argument, 0, (int) OPT_FLUSH},
#ifdef HAVE_GEMINI_DB
@@ -3036,6 +3042,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, SHOW_LONG},
{"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},
@@ -3248,6 +3257,7 @@ Starts the MySQL server\n");
--init-file=file Read SQL commands from this file at startup\n\
-L, --language=... Client error messages in given language. May be\n\
given as a full path\n\
+ --local-infile=[1|0] Enable/disable LOAD DATA LOCAL INFILE\n\
-l, --log[=file] Log connections and queries to file\n\
--log-bin[=file] Log queries in new binary format (for replication)\n\
--log-bin-index=file File that holds the names for last binary log files\n\
@@ -3311,10 +3321,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");
@@ -3411,9 +3423,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 */
{
@@ -3424,9 +3437,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 )
@@ -3462,17 +3475,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;
@@ -3806,11 +3819,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;
@@ -3853,10 +3871,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"
@@ -4086,16 +4104,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);
(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;
}
@@ -4103,7 +4122,7 @@ static void fix_paths(void)
char *tmp= (char*) my_malloc(FN_REFLEN,MYF(MY_FAE));
if (tmp)
{
- strmov(tmp,mysql_tmpdir);
+ strmake(tmp, mysql_tmpdir, FN_REFLEN-1);
mysql_tmpdir=tmp;
convert_dirname(mysql_tmpdir);
mysql_tmpdir=(char*) my_realloc(mysql_tmpdir,(uint) strlen(mysql_tmpdir)+1,
diff --git a/sql/share/Makefile.am b/sql/share/Makefile.am
index 6bc05aa33cd..b72f7493e20 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_acl.cc b/sql/sql_acl.cc
index 7ad778cf5d0..33924ada8ab 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -765,11 +765,6 @@ bool change_password(THD *thd, const char *host, const char *user,
char *new_password)
{
uint length=0;
- if (!user[0])
- {
- send_error(&thd->net, ER_PASSWORD_ANONYMOUS_USER);
- return 1;
- }
if (!initialized)
{
send_error(&thd->net, ER_PASSWORD_NOT_ALLOWED); /* purecov: inspected */
@@ -781,15 +776,21 @@ bool change_password(THD *thd, const char *host, const char *user,
length=(uint) strlen(new_password);
new_password[length & 16]=0;
- if (!thd || (!thd->slave_thread && ( strcmp(thd->user,user) ||
- my_strcasecmp(host,thd->host ? thd->host : thd->ip))))
+ if (!thd->slave_thread &&
+ (strcmp(thd->user,user) ||
+ my_strcasecmp(host,thd->host ? thd->host : thd->ip)))
{
if (check_access(thd, UPDATE_ACL, "mysql",0,1))
return 1;
}
+ if (!thd->slave_thread && !thd->user[0])
+ {
+ send_error(&thd->net, ER_PASSWORD_ANONYMOUS_USER);
+ return 1;
+ }
VOID(pthread_mutex_lock(&acl_cache->lock));
ACL_USER *acl_user;
- if (!(acl_user= find_acl_user(host,user)) || !acl_user->user)
+ if (!(acl_user= find_acl_user(host,user)))
{
send_error(&thd->net, ER_PASSWORD_NO_MATCH);
VOID(pthread_mutex_unlock(&acl_cache->lock));
@@ -797,7 +798,8 @@ bool change_password(THD *thd, const char *host, const char *user,
}
if (update_user_table(thd,
acl_user->host.hostname ? acl_user->host.hostname : "",
- acl_user->user, new_password))
+ acl_user->user ? acl_user->user : "",
+ new_password))
{
VOID(pthread_mutex_unlock(&acl_cache->lock)); /* purecov: deadcode */
send_error(&thd->net,0); /* purecov: deadcode */
@@ -817,7 +819,7 @@ bool change_password(THD *thd, const char *host, const char *user,
qinfo.q_len =
my_sprintf(buff,
(buff,"SET PASSWORD FOR \"%-.120s\"@\"%-.120s\"=\"%-.120s\"",
- acl_user->user,
+ acl_user->user ? acl_user->user : "",
acl_user->host.hostname ? acl_user->host.hostname : "",
new_password));
mysql_update_log.write(thd,buff,qinfo.q_len);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 1c281163b5a..e4a797efaaf 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -277,7 +277,6 @@ void intern_close_table(TABLE *table)
free_io_cache(table);
if (table->file)
VOID(closefrm(table)); // close file
- hash_free(&table->name_hash);
}
@@ -465,6 +464,7 @@ void close_thread_tables(THD *thd, bool locked)
unused_tables=table->next=table->prev=table;
}
}
+ thd->some_tables_deleted=0;
thd->open_tables=0;
/* Free tables to hold down open files */
while (open_cache.records > table_cache_size && unused_tables)
@@ -1718,7 +1718,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),
@@ -1734,7 +1734,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)))
{
@@ -2213,7 +2213,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_load.cc b/sql/sql_load.cc
index dd8487ceecc..1dcc8c2130e 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -72,7 +72,6 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
*enclosed=ex->enclosed;
bool is_fifo=0;
bool using_transactions;
-
DBUG_ENTER("mysql_load");
if (escaped->length() > 1 || enclosed->length() > 1)
@@ -260,8 +259,8 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (!read_file_from_client && mysql_bin_log.is_open())
{
ex->skip_lines = save_skip_lines;
- Load_log_event qinfo(thd, ex, table->table_name, fields,
- handle_duplicates);
+ Load_log_event qinfo(thd, ex, table->table_cache_key, table->table_name,
+ fields, handle_duplicates);
mysql_bin_log.write(&qinfo);
}
if (using_transactions)
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index 0f6e2f9fbf3..a6614f3f3f6 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -129,7 +129,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))
{
@@ -137,7 +137,7 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
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)
{
@@ -146,11 +146,11 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
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 673923765ad..c4383cbb09f 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1102,14 +1102,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;
@@ -2604,7 +2604,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)
@@ -2861,7 +2861,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)
@@ -2880,7 +2880,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)
@@ -3120,7 +3120,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)
@@ -3165,22 +3165,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;
}
@@ -4972,7 +4972,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));
@@ -6153,7 +6153,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;
@@ -6180,7 +6180,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 6ae7eeb41d3..018b43b11c8 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -889,9 +889,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];
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 54a03d4a714..0cbf6f45194 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -30,7 +30,7 @@
extern void yyerror(const char*);
int yylex(void *yylval);
-#define yyoverflow(A,B,C,D,E,F) if (my_yyoverflow((B),(D),(F))) { yyerror((char*) (A)); return 2; }
+#define yyoverflow(A,B,C,D,E,F) if (my_yyoverflow((B),(D),(int*) (F))) { yyerror((char*) (A)); return 2; }
inline Item *or_or_concat(Item* A, Item* B)
{
diff --git a/sql/table.cc b/sql/table.cc
index ce7d185a7a1..66cbe7cfa16 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -130,8 +130,8 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0)));
if (read_string(file,(gptr*) &disk_buff,(uint) uint2korr(head+28)))
goto err_not_open; /* purecov: inspected */
- outparam->keys=keys=disk_buff[0];
- outparam->keys_in_use= (((key_map) 1) << keys)- (key_map) 1;
+ outparam->keys=keys= disk_buff[0];
+ outparam->keys_in_use= set_bits(key_map, keys);
outparam->key_parts=key_parts=disk_buff[1];
n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
@@ -573,6 +573,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
delete outparam->file;
outparam->file=0; // For easyer errorchecking
outparam->db_stat=0;
+ hash_free(&outparam->name_hash);
free_root(&outparam->mem_root,MYF(0));
my_free(outparam->table_name,MYF(MY_ALLOW_ZERO_PTR));
DBUG_RETURN (error);
@@ -600,6 +601,7 @@ int closefrm(register TABLE *table)
}
delete table->file;
table->file=0; /* For easyer errorchecking */
+ hash_free(&table->name_hash);
free_root(&table->mem_root,MYF(0));
DBUG_RETURN(error);
}