summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--innobase/dict/dict0dict.c21
-rw-r--r--libmysql/libmysql.c11
-rw-r--r--sql/ha_innodb.cc6
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/sql_show.cc9
5 files changed, 41 insertions, 8 deletions
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index 18f27602cf0..563ca2521a4 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -1113,6 +1113,7 @@ dict_index_add_to_cache(
ulint n_ord;
ibool success;
ulint i;
+ ulint j;
ut_ad(index);
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -1143,6 +1144,26 @@ dict_index_add_to_cache(
return(FALSE);
}
+ /* Check that the same column does not appear twice in the index.
+ InnoDB assumes this in its algorithms, e.g., update of an index
+ entry */
+
+ for (i = 0; i < dict_index_get_n_fields(index); i++) {
+
+ for (j = 0; j < i; j++) {
+ if (dict_index_get_nth_field(index, j)->col
+ == dict_index_get_nth_field(index, i)->col) {
+
+ fprintf(stderr,
+"InnoDB: Error: column %s appears twice in index %s of table %s\n"
+"InnoDB: This is not allowed in InnoDB.\n"
+"InnoDB: UPDATE can cause such an index to become corrupt in InnoDB.\n",
+ dict_index_get_nth_field(index, i)->col->name,
+ index->name, table->name);
+ }
+ }
+ }
+
/* Build the cache internal representation of the index,
containing also the added system fields */
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 6965c1d79d8..49c110c738d 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -982,7 +982,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
else
{
cur->data[field] = to;
- if (to+len > end_to)
+ if (len > (ulong) (end_to - to))
{
free_rows(result);
net->last_errno=CR_MALFORMED_PACKET;
@@ -1023,7 +1023,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
{
uint field;
ulong pkt_len,len;
- uchar *pos,*prev_pos;
+ uchar *pos,*prev_pos, *end_pos;
if ((pkt_len=net_safe_read(mysql)) == packet_error)
return -1;
@@ -1031,6 +1031,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
return 1; /* End of data */
prev_pos= 0; /* allowed to write at packet[-1] */
pos=mysql->net.read_pos;
+ end_pos=pos+pkt_len;
for (field=0 ; field < fields ; field++)
{
if ((len=(ulong) net_field_length(&pos)) == NULL_LENGTH)
@@ -1040,6 +1041,12 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
}
else
{
+ if (len > (ulong) (end_pos - pos))
+ {
+ mysql->net.last_errno=CR_UNKNOWN_ERROR;
+ strmov(mysql->net.last_error,ER(mysql->net.last_errno));
+ return -1;
+ }
row[field] = (char*) pos;
pos+=len;
*lengths++=len;
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 2868011c443..b11c31f1d23 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -225,10 +225,14 @@ convert_error_code_to_mysql(
return(HA_ERR_ROW_IS_REFERENCED);
- } else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) {
+ } else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) {
return(HA_ERR_CANNOT_ADD_FOREIGN);
+ } else if (error == (int) DB_COL_APPEARS_TWICE_IN_INDEX) {
+
+ return(HA_ERR_WRONG_TABLE_DEF);
+
} else if (error == (int) DB_OUT_OF_FILE_SPACE) {
return(HA_ERR_RECORD_FILE_FULL);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 2c15b21ac7d..1a575932417 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -203,7 +203,7 @@ static char **opt_argv;
#else
#define MYSQL_SERVER_SUFFIX ""
#endif /* __NT__ */
-#endif
+#endif /* __WIN__ */
#ifdef HAVE_BERKELEY_DB
SHOW_COMP_OPTION have_berkeley_db=SHOW_OPTION_YES;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 8dfe5e9e948..02f4655c655 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1046,6 +1046,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
THD *tmp;
while ((tmp=it++))
{
+ struct st_my_thread_var *mysys_var;
if ((tmp->net.vio || tmp->system_thread) &&
(!user || (tmp->user && !strcmp(tmp->user,user))))
{
@@ -1062,8 +1063,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
if ((thd_info->db=tmp->db)) // Safe test
thd_info->db=thd->strdup(thd_info->db);
thd_info->command=(int) tmp->command;
- if (tmp->mysys_var)
- pthread_mutex_lock(&tmp->mysys_var->mutex);
+ if ((mysys_var= tmp->mysys_var))
+ pthread_mutex_lock(&mysys_var->mutex);
thd_info->proc_info= (char*) (tmp->killed ? "Killed" : 0);
thd_info->state_info= (char*) (tmp->locked ? "Locked" :
tmp->net.reading_or_writing ?
@@ -1075,8 +1076,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
tmp->mysys_var &&
tmp->mysys_var->current_cond ?
"Waiting on cond" : NullS);
- if (tmp->mysys_var)
- pthread_mutex_unlock(&tmp->mysys_var->mutex);
+ if (mysys_var)
+ pthread_mutex_unlock(&mysys_var->mutex);
#if !defined(DONT_USE_THR_ALARM) && ! defined(SCO)
if (pthread_kill(tmp->real_id,0))