Commit 8d1e5a5b authored by patg@govinda.patg.net's avatar patg@govinda.patg.net

Merge govinda.patg.net:/home/patg/mysql-build/mysql-5.0-holyfoot

into  govinda.patg.net:/home/patg/mysql-build/mysql-5.1-5.0-merge2

Push by holyfoot@production.mysql.com on Tue Jul 25 13:41:40 2006:

bk clone -l -r'holyfoot/hf@mysql.com/deer.(none)|ChangeSet|20060725085017|41021' mysql-5.0 tmp_merge
parents a4eb61b8 a9a345d9
...@@ -370,8 +370,9 @@ enum ha_base_keytype { ...@@ -370,8 +370,9 @@ enum ha_base_keytype {
would lead to a duplicate key would lead to a duplicate key
error in some other table. */ error in some other table. */
#define HA_ERR_TABLE_NEEDS_UPGRADE 164 /* The table changed in storage engine */ #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. */ /* Add error numbers before HA_ERR_LAST and change it accordingly. */
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1) #define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
......
...@@ -894,10 +894,14 @@ bool Protocol::send_fields(List<Item> *list, uint flags) ...@@ -894,10 +894,14 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
} }
else else
{ {
uint max_char_len;
/* With conversion */ /* With conversion */
client_field->charsetnr= thd_cs->number; client_field->charsetnr= thd_cs->number;
uint char_len= server_field.length / item->collation.collation->mbmaxlen; max_char_len= (server_field.type >= (int) MYSQL_TYPE_TINY_BLOB &&
client_field->length= char_len * thd_cs->mbmaxlen; 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->type= server_field.type;
client_field->flags= server_field.flags; client_field->flags= server_field.flags;
......
...@@ -1603,6 +1603,44 @@ fld_cid fld_name fld_parentid fld_delt ...@@ -1603,6 +1603,44 @@ fld_cid fld_name fld_parentid fld_delt
5 Torkel 0 0 5 Torkel 0 0
DROP TABLE federated.t1; DROP TABLE federated.t1;
DROP TABLE federated.bug_17377_table; 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; drop table if exists federated.t1;
create table federated.t1 (a int, b int, c int); create table federated.t1 (a int, b int, c int);
drop table if exists federated.t1; drop table if exists federated.t1;
...@@ -1733,6 +1771,19 @@ id val ...@@ -1733,6 +1771,19 @@ id val
2 0 2 0
drop table t1; drop table t1;
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 End of 5.0 tests
DROP TABLE IF EXISTS federated.t1; DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated; DROP DATABASE IF EXISTS federated;
......
...@@ -777,3 +777,15 @@ create table tm (b bit(1)) engine = merge union = (t1,t2); ...@@ -777,3 +777,15 @@ create table tm (b bit(1)) engine = merge union = (t1,t2);
select * from tm; select * from tm;
b b
drop table tm, t1, t2; 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
...@@ -1366,6 +1366,62 @@ drop table federated.t1, federated.t2; ...@@ -1366,6 +1366,62 @@ drop table federated.t1, federated.t2;
connection master; connection master;
--enable_parsing --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 # Additional test for bug#18437 "Wrong values inserted with a before
# update trigger on NDB table". SQL-layer didn't properly inform # update trigger on NDB table". SQL-layer didn't properly inform
...@@ -1479,7 +1535,23 @@ drop table t1; ...@@ -1479,7 +1535,23 @@ drop table t1;
connection master; connection master;
drop table t1; 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; source include/federated_cleanup.inc;
...@@ -392,4 +392,19 @@ create table tm (b bit(1)) engine = merge union = (t1,t2); ...@@ -392,4 +392,19 @@ create table tm (b bit(1)) engine = merge union = (t1,t2);
select * from tm; select * from tm;
drop table tm, t1, t2; 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
...@@ -1572,104 +1572,6 @@ Field *Field::new_key_field(MEM_ROOT *root, struct st_table *new_table, ...@@ -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 */ /* This is used to generate a field in TABLE from TABLE_SHARE */
Field *Field::clone(MEM_ROOT *root, struct st_table *new_table) Field *Field::clone(MEM_ROOT *root, struct st_table *new_table)
......
...@@ -268,8 +268,6 @@ public: ...@@ -268,8 +268,6 @@ public:
ptr= old_ptr; ptr= old_ptr;
return str; return str;
} }
bool quote_data(String *unquoted_string);
bool needs_quotes(void);
virtual bool send_binary(Protocol *protocol); virtual bool send_binary(Protocol *protocol);
virtual char *pack(char* to, const char *from, uint max_length=~(uint) 0) virtual char *pack(char* to, const char *from, uint max_length=~(uint) 0)
{ {
......
...@@ -124,11 +124,6 @@ ...@@ -124,11 +124,6 @@
ha_federated::write_row ha_federated::write_row
<for every field/column>
Field::quote_data
Field::quote_data
</for every field/column>
ha_federated::reset ha_federated::reset
(UPDATE) (UPDATE)
...@@ -138,20 +133,10 @@ ...@@ -138,20 +133,10 @@
ha_federated::index_init ha_federated::index_init
ha_federated::index_read ha_federated::index_read
ha_federated::index_read_idx ha_federated::index_read_idx
Field::quote_data
ha_federated::rnd_next ha_federated::rnd_next
ha_federated::convert_row_to_internal_format ha_federated::convert_row_to_internal_format
ha_federated::update_row 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 ha_federated::extra
ha_federated::extra ha_federated::extra
...@@ -1157,7 +1142,7 @@ bool ha_federated::create_where_from_key(String *to, ...@@ -1157,7 +1142,7 @@ bool ha_federated::create_where_from_key(String *to,
Field *field= key_part->field; Field *field= key_part->field;
uint store_length= key_part->store_length; uint store_length= key_part->store_length;
uint part_length= min(store_length, 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); DBUG_DUMP("key, start of loop", (char *) ptr, length);
if (key_part->null_bit) if (key_part->null_bit)
...@@ -1578,7 +1563,62 @@ inline uint field_in_record_is_null(TABLE *table, ...@@ -1578,7 +1563,62 @@ inline uint field_in_record_is_null(TABLE *table,
int ha_federated::write_row(byte *buf) 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 insert_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char values_buffer[FEDERATED_QUERY_BUFFER_SIZE]; char values_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char insert_field_value_buffer[STRING_BUFFER_USUAL_SIZE]; char insert_field_value_buffer[STRING_BUFFER_USUAL_SIZE];
...@@ -1594,10 +1634,6 @@ int ha_federated::write_row(byte *buf) ...@@ -1594,10 +1634,6 @@ int ha_federated::write_row(byte *buf)
&my_charset_bin); &my_charset_bin);
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set); my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
DBUG_ENTER("ha_federated::write_row"); 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); values_string.length(0);
insert_string.length(0); insert_string.length(0);
...@@ -1609,37 +1645,33 @@ int ha_federated::write_row(byte *buf) ...@@ -1609,37 +1645,33 @@ int ha_federated::write_row(byte *buf)
/* /*
start both our field and field values strings 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(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 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 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++) 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)) if (bitmap_is_set(table->write_set, (*field)->field_index))
{ {
/* commas_added= TRUE;
There are some fields. This will be used later to determine
whether to chop off commas and parens.
*/
has_fields= TRUE;
if ((*field)->is_null()) if ((*field)->is_null())
insert_field_value_string.append(STRING_WITH_LEN(" NULL ")); insert_field_value_string.append(STRING_WITH_LEN(" NULL "));
else else
{ {
(*field)->val_str(&insert_field_value_string); (*field)->val_str(&insert_field_value_string);
/* quote these fields if they require it */ values_string.append('\'');
(*field)->quote_data(&insert_field_value_string); insert_field_value_string.print(&values_string);
values_string.append('\'');
insert_field_value_string.length(0);
} }
/* append the field name */ /* append the field name */
insert_string.append((*field)->field_name); insert_string.append((*field)->field_name);
...@@ -1665,10 +1697,10 @@ int ha_federated::write_row(byte *buf) ...@@ -1665,10 +1697,10 @@ int ha_federated::write_row(byte *buf)
AND, we don't want to chop off the last char '(' AND, we don't want to chop off the last char '('
insert will be "INSERT INTO t1 VALUES ();" 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); insert_string.length(insert_string.length() - sizeof_trailing_comma);
/* chops off leading commas */
values_string.length(values_string.length() - sizeof_trailing_comma); values_string.length(values_string.length() - sizeof_trailing_comma);
insert_string.append(STRING_WITH_LEN(") ")); insert_string.append(STRING_WITH_LEN(") "));
} }
...@@ -1678,6 +1710,7 @@ int ha_federated::write_row(byte *buf) ...@@ -1678,6 +1710,7 @@ int ha_federated::write_row(byte *buf)
insert_string.length(insert_string.length() - sizeof_trailing_closeparen); 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(") ")); values_string.append(STRING_WITH_LEN(") "));
/* add the values */ /* add the values */
...@@ -1799,6 +1832,7 @@ int ha_federated::update_row(const byte *old_data, byte *new_data) ...@@ -1799,6 +1832,7 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
this. this.
*/ */
bool has_a_primary_key= test(table->s->primary_key != MAX_KEY); bool has_a_primary_key= test(table->s->primary_key != MAX_KEY);
/* /*
buffers for following strings buffers for following strings
*/ */
...@@ -1844,7 +1878,7 @@ int ha_federated::update_row(const byte *old_data, byte *new_data) ...@@ -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)) if (bitmap_is_set(table->write_set, (*field)->field_index))
{ {
update_string.append((*field)->field_name); update_string.append((*field)->field_name);
update_string.append(STRING_WITH_LEN("=")); update_string.append(STRING_WITH_LEN(" = "));
if ((*field)->is_null()) if ((*field)->is_null())
update_string.append(STRING_WITH_LEN(" NULL ")); update_string.append(STRING_WITH_LEN(" NULL "));
...@@ -1853,8 +1887,9 @@ int ha_federated::update_row(const byte *old_data, byte *new_data) ...@@ -1853,8 +1887,9 @@ 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); my_bitmap_map *old_map= tmp_use_all_columns(table, table->read_set);
/* otherwise = */ /* otherwise = */
(*field)->val_str(&field_value); (*field)->val_str(&field_value);
(*field)->quote_data(&field_value); update_string.append('\'');
update_string.append(field_value); field_value.print(&update_string);
update_string.append('\'');
field_value.length(0); field_value.length(0);
tmp_restore_column_map(table->read_set, old_map); 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) ...@@ -1871,8 +1906,9 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
where_string.append(STRING_WITH_LEN(" = ")); where_string.append(STRING_WITH_LEN(" = "));
(*field)->val_str(&field_value, (*field)->val_str(&field_value,
(char*) (old_data + (*field)->offset())); (char*) (old_data + (*field)->offset()));
(*field)->quote_data(&field_value); where_string.append('\'');
where_string.append(field_value); field_value.print(&where_string);
where_string.append('\'');
field_value.length(0); field_value.length(0);
} }
where_string.append(STRING_WITH_LEN(" AND ")); where_string.append(STRING_WITH_LEN(" AND "));
...@@ -1881,6 +1917,7 @@ int ha_federated::update_row(const byte *old_data, byte *new_data) ...@@ -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 */ /* Remove last ', '. This works as there must be at least on updated field */
update_string.length(update_string.length() - sizeof_trailing_comma); update_string.length(update_string.length() - sizeof_trailing_comma);
if (where_string.length()) if (where_string.length())
{ {
/* chop off trailing AND */ /* chop off trailing AND */
...@@ -1948,8 +1985,9 @@ int ha_federated::delete_row(const byte *buf) ...@@ -1948,8 +1985,9 @@ int ha_federated::delete_row(const byte *buf)
{ {
delete_string.append(STRING_WITH_LEN(" = ")); delete_string.append(STRING_WITH_LEN(" = "));
cur_field->val_str(&data_string); cur_field->val_str(&data_string);
cur_field->quote_data(&data_string); delete_string.append('\'');
delete_string.append(data_string); data_string.print(&delete_string);
delete_string.append('\'');
} }
delete_string.append(STRING_WITH_LEN(" AND ")); delete_string.append(STRING_WITH_LEN(" AND "));
} }
......
...@@ -122,6 +122,10 @@ int ha_myisammrg::close(void) ...@@ -122,6 +122,10 @@ int ha_myisammrg::close(void)
int ha_myisammrg::write_row(byte * buf) int ha_myisammrg::write_row(byte * buf)
{ {
statistic_increment(table->in_use->status_var.ha_write_count,&LOCK_status); 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) if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time(); table->timestamp_field->set_time();
if (table->next_number_field && buf == table->record[0]) if (table->next_number_field && buf == table->record[0])
......
...@@ -344,6 +344,7 @@ static int ha_init_errors(void) ...@@ -344,6 +344,7 @@ static int ha_init_errors(void)
SETMSG(HA_ERR_TABLE_DEF_CHANGED, ER(ER_TABLE_DEF_CHANGED)); 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_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_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(). */ /* Register the error messages for use with my_error(). */
return my_error_register(errmsgs, HA_ERR_FIRST, HA_ERR_LAST); return my_error_register(errmsgs, HA_ERR_FIRST, HA_ERR_LAST);
...@@ -2115,6 +2116,9 @@ void handler::print_error(int error, myf errflag) ...@@ -2115,6 +2116,9 @@ void handler::print_error(int error, myf errflag)
case HA_ERR_TABLE_NEEDS_UPGRADE: case HA_ERR_TABLE_NEEDS_UPGRADE:
textno=ER_TABLE_NEEDS_UPGRADE; textno=ER_TABLE_NEEDS_UPGRADE;
break; break;
case HA_ERR_TABLE_READONLY:
textno= ER_OPEN_AS_READONLY;
break;
default: default:
{ {
/* The error was "unknown" to this function. /* The error was "unknown" to this function.
......
...@@ -26,8 +26,7 @@ ...@@ -26,8 +26,7 @@
*/ */
#include "my_base.h" /* Defines EOVERFLOW on Windows */ #include "my_base.h" /* Includes errno.h + EOVERFLOW */
#include "my_global.h" /* Includes errno.h */
#include "m_ctype.h" #include "m_ctype.h"
#define MAX_DBL_EXP 308 #define MAX_DBL_EXP 308
......
...@@ -552,15 +552,18 @@ fi ...@@ -552,15 +552,18 @@ fi
%doc %attr(644, root, root) %{_infodir}/mysql.info* %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/myisamchk.1*
%doc %attr(644, root, man) %{_mandir}/man1/myisamlog.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/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.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysqld_multi.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/mysqld_safe.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysql_fix_privilege_tables.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/mysql_upgrade.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysqlhotcopy.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/mysqlmanager.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysql.server.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql.server.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysql_zap.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql_zap.1*
...@@ -646,7 +649,6 @@ fi ...@@ -646,7 +649,6 @@ fi
%files ndb-management %files ndb-management
%defattr(-,root,root,0755) %defattr(-,root,root,0755)
%attr(755, root, root) %{_sbindir}/ndb_mgmd %attr(755, root, root) %{_sbindir}/ndb_mgmd
%attr(755, root, root) %{_bindir}/ndb_mgm
%files ndb-tools %files ndb-tools
%defattr(-,root,root,0755) %defattr(-,root,root,0755)
......
...@@ -15490,7 +15490,9 @@ static struct my_tests_st my_tests[]= { ...@@ -15490,7 +15490,9 @@ static struct my_tests_st my_tests[]= {
{ "test_bug14845", test_bug14845 }, { "test_bug14845", test_bug14845 },
{ "test_opt_reconnect", test_opt_reconnect }, { "test_opt_reconnect", test_opt_reconnect },
{ "test_bug15510", test_bug15510}, { "test_bug15510", test_bug15510},
#ifndef EMBEDDED_LIBRARY
{ "test_bug12744", test_bug12744 }, { "test_bug12744", test_bug12744 },
#endif
{ "test_bug16143", test_bug16143 }, { "test_bug16143", test_bug16143 },
{ "test_bug16144", test_bug16144 }, { "test_bug16144", test_bug16144 },
{ "test_bug15613", test_bug15613 }, { "test_bug15613", test_bug15613 },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment