summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/my_base.h3
-rw-r--r--libmysqld/lib_sql.cc8
-rw-r--r--mysql-test/r/federated.result51
-rw-r--r--mysql-test/r/merge.result12
-rw-r--r--mysql-test/t/federated.test76
-rw-r--r--mysql-test/t/merge.test17
-rw-r--r--sql/field.cc98
-rw-r--r--sql/field.h2
-rw-r--r--sql/ha_federated.cc134
-rw-r--r--sql/ha_myisammrg.cc4
-rw-r--r--sql/handler.cc4
-rw-r--r--strings/strtod.c3
-rw-r--r--support-files/mysql.spec.sh4
-rw-r--r--tests/mysql_client_test.c2
14 files changed, 261 insertions, 157 deletions
diff --git a/include/my_base.h b/include/my_base.h
index d75df093a11..3d1afed3949 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -370,8 +370,9 @@ enum ha_base_keytype {
would lead to a duplicate key
error in some other table. */
#define HA_ERR_TABLE_NEEDS_UPGRADE 164 /* The table changed in storage engine */
+#define HA_ERR_TABLE_READONLY 165 /* The table is not writable */
-#define HA_ERR_LAST 164 /*Copy last error nr.*/
+#define HA_ERR_LAST 165 /*Copy last error nr.*/
/* Add error numbers before HA_ERR_LAST and change it accordingly. */
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 14dbe21fce0..6f9165f5018 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -894,10 +894,14 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
}
else
{
+ uint max_char_len;
/* With conversion */
client_field->charsetnr= thd_cs->number;
- uint char_len= server_field.length / item->collation.collation->mbmaxlen;
- client_field->length= char_len * thd_cs->mbmaxlen;
+ max_char_len= (server_field.type >= (int) MYSQL_TYPE_TINY_BLOB &&
+ server_field.type <= (int) MYSQL_TYPE_BLOB) ?
+ server_field.length / item->collation.collation->mbminlen :
+ server_field.length / item->collation.collation->mbmaxlen;
+ client_field->length= max_char_len * thd_cs->mbmaxlen;
}
client_field->type= server_field.type;
client_field->flags= server_field.flags;
diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result
index 4bb279add69..97d138cfc76 100644
--- a/mysql-test/r/federated.result
+++ b/mysql-test/r/federated.result
@@ -1603,6 +1603,44 @@ fld_cid fld_name fld_parentid fld_delt
5 Torkel 0 0
DROP TABLE federated.t1;
DROP TABLE federated.bug_17377_table;
+DROP TABLE IF EXISTS federated.test;
+CREATE TABLE federated.test (
+`id` int(11) NOT NULL,
+`val1` varchar(255) NOT NULL,
+`val2` varchar(255) NOT NULL,
+PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+DROP TABLE IF EXISTS federated.test_local;
+DROP TABLE IF EXISTS federated.test_remote;
+CREATE TABLE federated.test_local (
+`id` int(11) NOT NULL,
+`val1` varchar(255) NOT NULL,
+`val2` varchar(255) NOT NULL,
+PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO federated.test_local VALUES (1, 'foo', 'bar'),
+(2, 'bar', 'foo');
+CREATE TABLE federated.test_remote (
+`id` int(11) NOT NULL,
+`val1` varchar(255) NOT NULL,
+`val2` varchar(255) NOT NULL,
+PRIMARY KEY (`id`)
+) ENGINE=FEDERATED DEFAULT CHARSET=latin1
+CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/test';
+insert into federated.test_remote select * from federated.test_local;
+select * from federated.test_remote;
+id val1 val2
+1 foo bar
+2 bar foo
+delete from federated.test_remote where id in (1,2);
+insert into federated.test_remote select * from federated.test_local;
+select * from federated.test_remote;
+id val1 val2
+2 bar foo
+1 foo bar
+DROP TABLE federated.test_local;
+DROP TABLE federated.test_remote;
+DROP TABLE federated.test;
drop table if exists federated.t1;
create table federated.t1 (a int, b int, c int);
drop table if exists federated.t1;
@@ -1733,6 +1771,19 @@ id val
2 0
drop table t1;
drop table t1;
+create table t1 (a longblob not null);
+create table t1
+(a longblob not null) engine=federated
+connection='mysql://root@127.0.0.1:SLAVE_PORT/test/t1';
+insert into t1 values (repeat('a',5000));
+select length(a) from t1;
+length(a)
+5000
+select length(a) from t1;
+length(a)
+5000
+drop table t1;
+drop table t1;
End of 5.0 tests
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index b8cdc99abdc..db2c462398f 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -777,3 +777,15 @@ create table tm (b bit(1)) engine = merge union = (t1,t2);
select * from tm;
b
drop table tm, t1, t2;
+create table t1 (a int) insert_method = last engine = merge;
+insert into t1 values (1);
+ERROR HY000: Table 't1' is read only
+create table t2 (a int) engine = myisam;
+alter table t1 union (t2);
+insert into t1 values (1);
+alter table t1 insert_method = no;
+insert into t1 values (1);
+ERROR HY000: Table 't1' is read only
+drop table t2;
+drop table t1;
+End of 5.0 tests
diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test
index 032e2536f0a..8e4e45808b6 100644
--- a/mysql-test/t/federated.test
+++ b/mysql-test/t/federated.test
@@ -1366,6 +1366,62 @@ drop table federated.t1, federated.t2;
connection master;
--enable_parsing
+#
+# BUG #18764: Delete conditions causing inconsistencies in Federated tables
+#
+connection slave;
+--disable_warnings
+DROP TABLE IF EXISTS federated.test;
+--enable_warnings
+CREATE TABLE federated.test (
+ `id` int(11) NOT NULL,
+ `val1` varchar(255) NOT NULL,
+ `val2` varchar(255) NOT NULL,
+ PRIMARY KEY (`id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+connection master;
+--disable_warnings
+DROP TABLE IF EXISTS federated.test_local;
+DROP TABLE IF EXISTS federated.test_remote;
+--enable_warnings
+CREATE TABLE federated.test_local (
+ `id` int(11) NOT NULL,
+ `val1` varchar(255) NOT NULL,
+ `val2` varchar(255) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+INSERT INTO federated.test_local VALUES (1, 'foo', 'bar'),
+(2, 'bar', 'foo');
+
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval CREATE TABLE federated.test_remote (
+ `id` int(11) NOT NULL,
+ `val1` varchar(255) NOT NULL,
+ `val2` varchar(255) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=FEDERATED DEFAULT CHARSET=latin1
+CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/test';
+
+insert into federated.test_remote select * from federated.test_local;
+
+select * from federated.test_remote;
+
+delete from federated.test_remote where id in (1,2);
+
+insert into federated.test_remote select * from federated.test_local;
+
+select * from federated.test_remote;
+--disable_warnings
+DROP TABLE federated.test_local;
+DROP TABLE federated.test_remote;
+--enable_warnings
+connection slave;
+--disable_warnings
+DROP TABLE federated.test;
+--enable_warnings
+
#
# Additional test for bug#18437 "Wrong values inserted with a before
# update trigger on NDB table". SQL-layer didn't properly inform
@@ -1479,7 +1535,23 @@ drop table t1;
connection master;
drop table t1;
---echo End of 5.0 tests
+#
+# Bug #17608: String literals lost during INSERT query on FEDERATED table
+#
+connection slave;
+create table t1 (a longblob not null);
+connection master;
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval create table t1
+ (a longblob not null) engine=federated
+ connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1';
+insert into t1 values (repeat('a',5000));
+select length(a) from t1;
+connection slave;
+select length(a) from t1;
+drop table t1;
+connection master;
+drop table t1;
+--echo End of 5.0 tests
source include/federated_cleanup.inc;
-
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index 33282348325..f8bed9c92cd 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -392,4 +392,19 @@ create table tm (b bit(1)) engine = merge union = (t1,t2);
select * from tm;
drop table tm, t1, t2;
-# End of 5.0 tests
+#
+# Bug #17766: The server accepts to create MERGE tables which cannot work
+#
+create table t1 (a int) insert_method = last engine = merge;
+--error ER_OPEN_AS_READONLY
+insert into t1 values (1);
+create table t2 (a int) engine = myisam;
+alter table t1 union (t2);
+insert into t1 values (1);
+alter table t1 insert_method = no;
+--error ER_OPEN_AS_READONLY
+insert into t1 values (1);
+drop table t2;
+drop table t1;
+
+--echo End of 5.0 tests
diff --git a/sql/field.cc b/sql/field.cc
index 4a9487ff7a9..53948f571c5 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1572,104 +1572,6 @@ Field *Field::new_key_field(MEM_ROOT *root, struct st_table *new_table,
}
-/*
- SYNOPSIS
- Field::quote_data()
- unquoted_string Pointer pointing to the value of a field
-
- DESCRIPTION
- Simple method that passes the field type to the method "type_quote"
- To get a true/false value as to whether the value in string1 needs
- to be enclosed with quotes. This ensures that values in the final
- sql statement to be passed to the remote server will be quoted properly
-
- RETURN_VALUE
- void Immediately - if string doesn't need quote
- void Upon prepending/appending quotes on each side of variable
-
-*/
-
-bool Field::quote_data(String *unquoted_string)
-{
- char escaped_string[IO_SIZE];
- DBUG_ENTER("Field::quote_data");
-
- if (!needs_quotes())
- DBUG_RETURN(0);
-
- // this is the same call that mysql_real_escape_string() calls
- if (escape_string_for_mysql(&my_charset_bin, (char *)escaped_string,
- sizeof(escaped_string), unquoted_string->ptr(),
- unquoted_string->length()) == (ulong)~0)
- DBUG_RETURN(1);
-
- // reset string, then re-append with quotes and escaped values
- unquoted_string->length(0);
- if (unquoted_string->append('\'') ||
- unquoted_string->append((char *)escaped_string) ||
- unquoted_string->append('\''))
- DBUG_RETURN(1);
- DBUG_RETURN(0);
-}
-
-
-/*
- Quote a field type if needed
-
- SYNOPSIS
- Field::type_quote
-
- DESCRIPTION
- Simple method to give true/false whether a field should be quoted.
- Used when constructing INSERT and UPDATE queries to the remote server
- see write_row and update_row
-
- RETURN VALUE
- 0 if value is of type NOT needing quotes
- 1 if value is of type needing quotes
-*/
-
-bool Field::needs_quotes(void)
-{
- DBUG_ENTER("Field::type_quote");
-
- switch (type()) {
- //FIX this when kernel is fixed
- case MYSQL_TYPE_VARCHAR :
- case FIELD_TYPE_STRING :
- case FIELD_TYPE_VAR_STRING :
- case FIELD_TYPE_YEAR :
- case FIELD_TYPE_NEWDATE :
- case FIELD_TYPE_TIME :
- case FIELD_TYPE_TIMESTAMP :
- case FIELD_TYPE_DATE :
- case FIELD_TYPE_DATETIME :
- case FIELD_TYPE_TINY_BLOB :
- case FIELD_TYPE_BLOB :
- case FIELD_TYPE_MEDIUM_BLOB :
- case FIELD_TYPE_LONG_BLOB :
- case FIELD_TYPE_GEOMETRY :
- case FIELD_TYPE_BIT:
- DBUG_RETURN(1);
-
- case FIELD_TYPE_DECIMAL :
- case FIELD_TYPE_TINY :
- case FIELD_TYPE_SHORT :
- case FIELD_TYPE_INT24 :
- case FIELD_TYPE_LONG :
- case FIELD_TYPE_FLOAT :
- case FIELD_TYPE_DOUBLE :
- case FIELD_TYPE_LONGLONG :
- case FIELD_TYPE_NULL :
- case FIELD_TYPE_SET :
- case FIELD_TYPE_ENUM :
- DBUG_RETURN(0);
- default:
- DBUG_RETURN(0);
- }
-}
-
-
/* This is used to generate a field in TABLE from TABLE_SHARE */
Field *Field::clone(MEM_ROOT *root, struct st_table *new_table)
diff --git a/sql/field.h b/sql/field.h
index 3fba0ffbb00..cd6439d1787 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -268,8 +268,6 @@ public:
ptr= old_ptr;
return str;
}
- bool quote_data(String *unquoted_string);
- bool needs_quotes(void);
virtual bool send_binary(Protocol *protocol);
virtual char *pack(char* to, const char *from, uint max_length=~(uint) 0)
{
diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc
index fcceb3d2bab..bf3c3ac1beb 100644
--- a/sql/ha_federated.cc
+++ b/sql/ha_federated.cc
@@ -124,11 +124,6 @@
ha_federated::write_row
- <for every field/column>
- Field::quote_data
- Field::quote_data
- </for every field/column>
-
ha_federated::reset
(UPDATE)
@@ -138,20 +133,10 @@
ha_federated::index_init
ha_federated::index_read
ha_federated::index_read_idx
- Field::quote_data
ha_federated::rnd_next
ha_federated::convert_row_to_internal_format
ha_federated::update_row
- <quote 3 cols, new and old data>
- Field::quote_data
- Field::quote_data
- Field::quote_data
- Field::quote_data
- Field::quote_data
- Field::quote_data
- </quote 3 cols, new and old data>
-
ha_federated::extra
ha_federated::extra
ha_federated::extra
@@ -1157,7 +1142,7 @@ bool ha_federated::create_where_from_key(String *to,
Field *field= key_part->field;
uint store_length= key_part->store_length;
uint part_length= min(store_length, length);
- needs_quotes= field->needs_quotes();
+ needs_quotes= 1;
DBUG_DUMP("key, start of loop", (char *) ptr, length);
if (key_part->null_bit)
@@ -1578,7 +1563,62 @@ inline uint field_in_record_is_null(TABLE *table,
int ha_federated::write_row(byte *buf)
{
- bool has_fields= FALSE;
+ /*
+ I need a bool again, in 5.0, I used table->s->fields to accomplish this.
+ This worked as a flag that says there are fields with values or not.
+ In 5.1, this value doesn't work the same, and I end up with the code
+ truncating open parenthesis:
+
+ the statement "INSERT INTO t1 VALUES ()" ends up being first built
+ in two strings
+ "INSERT INTO t1 ("
+ and
+ " VALUES ("
+
+ If there are fields with values, they get appended, with commas, and
+ the last loop, a trailing comma is there
+
+ "INSERT INTO t1 ( col1, col2, colN, "
+
+ " VALUES ( 'val1', 'val2', 'valN', "
+
+ Then, if there are fields, it should decrement the string by ", " length.
+
+ "INSERT INTO t1 ( col1, col2, colN"
+ " VALUES ( 'val1', 'val2', 'valN'"
+
+ Then it adds a close paren to both - if there are fields
+
+ "INSERT INTO t1 ( col1, col2, colN)"
+ " VALUES ( 'val1', 'val2', 'valN')"
+
+ Then appends both together
+ "INSERT INTO t1 ( col1, col2, colN) VALUES ( 'val1', 'val2', 'valN')"
+
+ So... the problem, is if you have the original statement:
+
+ "INSERT INTO t1 VALUES ()"
+
+ Which is legitimate, but if the code thinks there are fields
+
+ "INSERT INTO t1 ("
+ " VALUES ( "
+
+ If the field flag is set, but there are no commas, reduces the
+ string by strlen(", ")
+
+ "INSERT INTO t1 "
+ " VALUES "
+
+ Then adds the close parenthesis
+
+ "INSERT INTO t1 )"
+ " VALUES )"
+
+ So, I have to use a bool as before, set in the loop where fields and commas
+ are appended to the string
+ */
+ my_bool commas_added= FALSE;
char insert_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char values_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char insert_field_value_buffer[STRING_BUFFER_USUAL_SIZE];
@@ -1594,10 +1634,6 @@ int ha_federated::write_row(byte *buf)
&my_charset_bin);
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
DBUG_ENTER("ha_federated::write_row");
- DBUG_PRINT("info",
- ("table charset name %s csname %s",
- table->s->table_charset->name,
- table->s->table_charset->csname));
values_string.length(0);
insert_string.length(0);
@@ -1609,37 +1645,33 @@ int ha_federated::write_row(byte *buf)
/*
start both our field and field values strings
*/
- insert_string.append(STRING_WITH_LEN("INSERT `"));
+ insert_string.append(STRING_WITH_LEN("INSERT INTO `"));
insert_string.append(share->table_name, share->table_name_length);
- insert_string.append(STRING_WITH_LEN("` ("));
+ insert_string.append('`');
+ insert_string.append(STRING_WITH_LEN(" ("));
- values_string.append(STRING_WITH_LEN(" VALUES ("));
+ values_string.append(STRING_WITH_LEN(" VALUES "));
+ values_string.append(STRING_WITH_LEN(" ("));
/*
loop through the field pointer array, add any fields to both the values
list and the fields list that is part of the write set
-
- You might ask "Why an index variable (has_fields) ?" My answer is that
- we need to count how many fields we actually need
*/
for (field= table->field; *field; field++)
{
- /* if there is a query id and if it's equal to the current query id */
if (bitmap_is_set(table->write_set, (*field)->field_index))
{
- /*
- There are some fields. This will be used later to determine
- whether to chop off commas and parens.
- */
- has_fields= TRUE;
-
+ commas_added= TRUE;
if ((*field)->is_null())
insert_field_value_string.append(STRING_WITH_LEN(" NULL "));
else
{
(*field)->val_str(&insert_field_value_string);
- /* quote these fields if they require it */
- (*field)->quote_data(&insert_field_value_string);
+ values_string.append('\'');
+ insert_field_value_string.print(&values_string);
+ values_string.append('\'');
+
+ insert_field_value_string.length(0);
}
/* append the field name */
insert_string.append((*field)->field_name);
@@ -1665,10 +1697,10 @@ int ha_federated::write_row(byte *buf)
AND, we don't want to chop off the last char '('
insert will be "INSERT INTO t1 VALUES ();"
*/
- if (has_fields)
+ if (commas_added)
{
- /* chops off trailing commas */
insert_string.length(insert_string.length() - sizeof_trailing_comma);
+ /* chops off leading commas */
values_string.length(values_string.length() - sizeof_trailing_comma);
insert_string.append(STRING_WITH_LEN(") "));
}
@@ -1678,6 +1710,7 @@ int ha_federated::write_row(byte *buf)
insert_string.length(insert_string.length() - sizeof_trailing_closeparen);
}
+ /* we always want to append this, even if there aren't any fields */
values_string.append(STRING_WITH_LEN(") "));
/* add the values */
@@ -1799,6 +1832,7 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
this.
*/
bool has_a_primary_key= test(table->s->primary_key != MAX_KEY);
+
/*
buffers for following strings
*/
@@ -1844,7 +1878,7 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
if (bitmap_is_set(table->write_set, (*field)->field_index))
{
update_string.append((*field)->field_name);
- update_string.append(STRING_WITH_LEN("="));
+ update_string.append(STRING_WITH_LEN(" = "));
if ((*field)->is_null())
update_string.append(STRING_WITH_LEN(" NULL "));
@@ -1852,9 +1886,10 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
{
my_bitmap_map *old_map= tmp_use_all_columns(table, table->read_set);
/* otherwise = */
- (*field)->val_str(&field_value);
- (*field)->quote_data(&field_value);
- update_string.append(field_value);
+ (*field)->val_str(&field_value);
+ update_string.append('\'');
+ field_value.print(&update_string);
+ update_string.append('\'');
field_value.length(0);
tmp_restore_column_map(table->read_set, old_map);
}
@@ -1871,8 +1906,9 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
where_string.append(STRING_WITH_LEN(" = "));
(*field)->val_str(&field_value,
(char*) (old_data + (*field)->offset()));
- (*field)->quote_data(&field_value);
- where_string.append(field_value);
+ where_string.append('\'');
+ field_value.print(&where_string);
+ where_string.append('\'');
field_value.length(0);
}
where_string.append(STRING_WITH_LEN(" AND "));
@@ -1881,6 +1917,7 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
/* Remove last ', '. This works as there must be at least on updated field */
update_string.length(update_string.length() - sizeof_trailing_comma);
+
if (where_string.length())
{
/* chop off trailing AND */
@@ -1946,10 +1983,11 @@ int ha_federated::delete_row(const byte *buf)
}
else
{
- delete_string.append(STRING_WITH_LEN(" = "));
- cur_field->val_str(&data_string);
- cur_field->quote_data(&data_string);
- delete_string.append(data_string);
+ delete_string.append(STRING_WITH_LEN(" = "));
+ cur_field->val_str(&data_string);
+ delete_string.append('\'');
+ data_string.print(&delete_string);
+ delete_string.append('\'');
}
delete_string.append(STRING_WITH_LEN(" AND "));
}
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index 17223a6e57c..a15787fdcf0 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -122,6 +122,10 @@ int ha_myisammrg::close(void)
int ha_myisammrg::write_row(byte * buf)
{
statistic_increment(table->in_use->status_var.ha_write_count,&LOCK_status);
+
+ if (file->merge_insert_method == MERGE_INSERT_DISABLED || !file->tables)
+ return (HA_ERR_TABLE_READONLY);
+
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
if (table->next_number_field && buf == table->record[0])
diff --git a/sql/handler.cc b/sql/handler.cc
index b356102a61a..0804f23f51e 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -344,6 +344,7 @@ static int ha_init_errors(void)
SETMSG(HA_ERR_TABLE_DEF_CHANGED, ER(ER_TABLE_DEF_CHANGED));
SETMSG(HA_ERR_FOREIGN_DUPLICATE_KEY, "FK constraint would lead to duplicate key");
SETMSG(HA_ERR_TABLE_NEEDS_UPGRADE, ER(ER_TABLE_NEEDS_UPGRADE));
+ SETMSG(HA_ERR_TABLE_READONLY, ER(ER_OPEN_AS_READONLY));
/* Register the error messages for use with my_error(). */
return my_error_register(errmsgs, HA_ERR_FIRST, HA_ERR_LAST);
@@ -2115,6 +2116,9 @@ void handler::print_error(int error, myf errflag)
case HA_ERR_TABLE_NEEDS_UPGRADE:
textno=ER_TABLE_NEEDS_UPGRADE;
break;
+ case HA_ERR_TABLE_READONLY:
+ textno= ER_OPEN_AS_READONLY;
+ break;
default:
{
/* The error was "unknown" to this function.
diff --git a/strings/strtod.c b/strings/strtod.c
index e0910205d2f..7171a6e0801 100644
--- a/strings/strtod.c
+++ b/strings/strtod.c
@@ -26,8 +26,7 @@
*/
-#include "my_base.h" /* Defines EOVERFLOW on Windows */
-#include "my_global.h" /* Includes errno.h */
+#include "my_base.h" /* Includes errno.h + EOVERFLOW */
#include "m_ctype.h"
#define MAX_DBL_EXP 308
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index 5d7c0ed154f..8dbf1bef7fe 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -552,15 +552,18 @@ fi
%doc %attr(644, root, root) %{_infodir}/mysql.info*
+%doc %attr(644, root, man) %{_mandir}/man1/myisam_ftdump.1*
%doc %attr(644, root, man) %{_mandir}/man1/myisamchk.1*
%doc %attr(644, root, man) %{_mandir}/man1/myisamlog.1*
%doc %attr(644, root, man) %{_mandir}/man1/myisampack.1*
+%doc %attr(644, root, man) %{_mandir}/man1/mysql_explain_log.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysqld.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysqld_multi.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysqld_safe.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysql_fix_privilege_tables.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysql_upgrade.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysqlhotcopy.1*
+%doc %attr(644, root, man) %{_mandir}/man1/mysqlman.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysqlmanager.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysql.server.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysql_zap.1*
@@ -646,7 +649,6 @@ fi
%files ndb-management
%defattr(-,root,root,0755)
%attr(755, root, root) %{_sbindir}/ndb_mgmd
-%attr(755, root, root) %{_bindir}/ndb_mgm
%files ndb-tools
%defattr(-,root,root,0755)
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index cbf8a1cbf01..eb5465d4d35 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -15490,7 +15490,9 @@ static struct my_tests_st my_tests[]= {
{ "test_bug14845", test_bug14845 },
{ "test_opt_reconnect", test_opt_reconnect },
{ "test_bug15510", test_bug15510},
+#ifndef EMBEDDED_LIBRARY
{ "test_bug12744", test_bug12744 },
+#endif
{ "test_bug16143", test_bug16143 },
{ "test_bug16144", test_bug16144 },
{ "test_bug15613", test_bug15613 },