summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Docs/internals.texi16
-rw-r--r--innobase/include/db0err.h3
-rw-r--r--mysql-test/r/insert.result11
-rw-r--r--sql/log.cc5
-rw-r--r--sql/log_event.cc23
-rw-r--r--sql/slave.cc7
-rw-r--r--sql/slave.h10
-rw-r--r--sql/sql_analyse.cc49
-rw-r--r--sql/sql_yacc.yy5
9 files changed, 93 insertions, 36 deletions
diff --git a/Docs/internals.texi b/Docs/internals.texi
index 7e364774e39..18bdc8d8b4c 100644
--- a/Docs/internals.texi
+++ b/Docs/internals.texi
@@ -1797,7 +1797,7 @@ The package contains the following information:
@multitable @columnfractions .30 .70
@item Size @tab Comment
-@item (param_count+7)/8 @tab Null bit map
+@item (param_count+9)/8 @tab Null bit map (2 bits reserved for protocol)
@item 1 @tab new_parameter_bound flag. Is set to 1 for first
execute or if one has rebound the parameters.
@item 2*param_count @tab Type of parameters (only given if new_parameter_bound flag is 1)
@@ -1813,7 +1813,7 @@ The parameters are stored the following ways:
@multitable @columnfractions .20 .10 .70
@item Type @tab Size @tab Comment
-@item tynyint @tab 1 @tab One byte integer
+@item tinyint @tab 1 @tab One byte integer
@item short @tab 2 @tab
@item int @tab 4 @tab
@item longlong @tab 8 @tab
@@ -1849,6 +1849,18 @@ bound parameters to the client. The server is always sending the data
as type given for 'column type' for respective column. It's up to the
client to convert the parameter to the requested type.
+DATETIME, DATE and TIME are sent to the server in a binary format as follows:
+
+@multitable @columnfractions .20 .10 .70
+@item Type @tab Size @tab Comment
+@item date @tab 1 + 0-11 @tab Length + 2 byte year, 1 byte MMDDHHMMSS, 4 byte billionth of a second
+@item datetime @tab 1 + 0-11 @tab Length + 2 byte year, 1 byte MMDDHHMMSS, 4 byte billionth of a second
+@item time @tab 1 + 0-14 @tab Length + sign (0 = pos, 1= neg), 4 byte days, 1 byte HHMMDD, 4 byte billionth of a second
+@end multitable
+
+The first byte is a length byte and then comes all parameters that are
+not 0. (Always counted from the beginning).
+
@node Fulltext Search, , protocol, Top
@chapter Fulltext Search in MySQL
diff --git a/innobase/include/db0err.h b/innobase/include/db0err.h
index 86b79b65bf2..ae4b0fe4cc5 100644
--- a/innobase/include/db0err.h
+++ b/innobase/include/db0err.h
@@ -42,7 +42,8 @@ Created 5/24/1996 Heikki Tuuri
#define DB_CANNOT_ADD_CONSTRAINT 38 /* adding a foreign key constraint
to a table failed */
#define DB_CORRUPTION 39 /* data structure corruption noticed */
-
+#define DB_COL_APPEARS_TWICE_IN_INDEX 40
+
/* The following are partial failure codes */
#define DB_FAIL 1000
#define DB_OVERFLOW 1001
diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result
index 2ffa9d88618..dedde4cc408 100644
--- a/mysql-test/r/insert.result
+++ b/mysql-test/r/insert.result
@@ -46,8 +46,17 @@ insert into t1 values ('skr',NULL),('skr',NULL),('test',NULL);
select * from t1;
sid id
skr 1
-skr 2
+skr 1
+test 1
+insert into t1 values ('rts',NULL),('rts',NULL),('test',NULL);
+select * from t1;
+sid id
+rts 1
+rts 2
+skr 1
+skr 1
test 1
+test 2
drop table t1;
drop database if exists foo;
create database foo;
diff --git a/sql/log.cc b/sql/log.cc
index 32dbdac1074..56019a76b22 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -654,7 +654,12 @@ int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli)
rli->linfo.log_file_name);
goto err;
}
+ /*
+ Reset position to current log. This involves setting both of the
+ position variables:
+ */
rli->relay_log_pos = BIN_LOG_HEADER_SIZE;
+ rli->pending = 0;
strmake(rli->relay_log_name,rli->linfo.log_file_name,
sizeof(rli->relay_log_name)-1);
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 373e50b84f7..d451a5bc46c 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -208,9 +208,13 @@ int Log_event::exec_event(struct st_relay_log_info* rli)
{
if (rli) // QQ When is this not true ?
{
- rli->inc_pos(get_event_len(),log_pos);
- DBUG_ASSERT(rli->sql_thd != 0);
- flush_relay_log_info(rli);
+ if (rli->inside_transaction)
+ rli->inc_pending(get_event_len());
+ else
+ {
+ rli->inc_pos(get_event_len(),log_pos);
+ flush_relay_log_info(rli);
+ }
}
return 0;
}
@@ -1707,6 +1711,19 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
mysql_log.write(thd,COM_QUERY,"%s",thd->query);
DBUG_PRINT("query",("%s",thd->query));
mysql_parse(thd, thd->query, q_len);
+
+ /*
+ Set a flag if we are inside an transaction so that we can restart
+ the transaction from the start if we are killed
+
+ This will only be done if we are supporting transactional tables
+ in the slave.
+ */
+ if (!strcmp(thd->query,"BEGIN"))
+ rli->inside_transaction= opt_using_transactions;
+ else if (!strcmp(thd->query,"COMMIT"))
+ rli->inside_transaction=0;
+
if ((expected_error != (actual_error = thd->net.last_errno)) &&
expected_error &&
!ignored_error_code(actual_error) &&
diff --git a/sql/slave.cc b/sql/slave.cc
index eb53e488856..a4e0b029bbf 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -2711,7 +2711,12 @@ static IO_CACHE *reopen_relay_log(RELAY_LOG_INFO *rli, const char **errmsg)
if ((rli->cur_log_fd=open_binlog(cur_log,rli->relay_log_name,
errmsg)) <0)
DBUG_RETURN(0);
- my_b_seek(cur_log,rli->relay_log_pos);
+ /*
+ We want to start exactly where we was before:
+ relay_log_pos Current log pos
+ pending Number of bytes already processed from the event
+ */
+ my_b_seek(cur_log,rli->relay_log_pos + rli->pending);
DBUG_RETURN(cur_log);
}
diff --git a/sql/slave.h b/sql/slave.h
index 721fd8534a0..cb368ad26b1 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -169,11 +169,13 @@ typedef struct st_relay_log_info
volatile bool abort_slave, slave_running;
bool log_pos_current;
bool skip_log_purge;
-
+ bool inside_transaction;
+
st_relay_log_info()
- :info_fd(-1),cur_log_fd(-1), cur_log_old_open_count(0), abort_pos_wait(0),
- slave_run_id(0), inited(0), abort_slave(0), slave_running(0),
- log_pos_current(0), skip_log_purge(0)
+ :info_fd(-1),cur_log_fd(-1), cur_log_old_open_count(0), abort_pos_wait(0),
+ slave_run_id(0), inited(0), abort_slave(0), slave_running(0),
+ log_pos_current(0), skip_log_purge(0),
+ inside_transaction(0) /* the default is autocommit=1 */
{
relay_log_name[0] = master_log_name[0] = 0;
bzero(&info_file,sizeof(info_file));
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index 96bbd731882..cbd586b8d30 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -310,30 +310,6 @@ void field_str::add()
was_maybe_zerofill = num_info.maybe_zerofill;
}
- if (room_in_tree)
- {
- if (res != &s)
- s.copy(*res);
- if (!tree_search(&tree, (void*) &s)) // If not in tree
- {
- s.copy(); // slow, when SAFE_MALLOC is in use
- if (!tree_insert(&tree, (void*) &s, 0))
- {
- room_in_tree = 0; // Remove tree, out of RAM ?
- delete_tree(&tree);
- }
- else
- {
- bzero((char*) &s, sizeof(s)); // Let tree handle free of this
- if ((treemem += length) > pc->max_treemem)
- {
- room_in_tree = 0; // Remove tree, too big tree
- delete_tree(&tree);
- }
- }
- }
- }
-
if (!found)
{
found = 1;
@@ -364,6 +340,31 @@ void field_str::add()
max_arg.copy(*res);
}
}
+
+ if (room_in_tree)
+ {
+ if (res != &s)
+ s.copy(*res);
+ if (!tree_search(&tree, (void*) &s)) // If not in tree
+ {
+ s.copy(); // slow, when SAFE_MALLOC is in use
+ if (!tree_insert(&tree, (void*) &s, 0))
+ {
+ room_in_tree = 0; // Remove tree, out of RAM ?
+ delete_tree(&tree);
+ }
+ else
+ {
+ bzero((char*) &s, sizeof(s)); // Let tree handle free of this
+ if ((treemem += length) > pc->max_treemem)
+ {
+ room_in_tree = 0; // Remove tree, too big tree
+ delete_tree(&tree);
+ }
+ }
+ }
+ }
+
if ((num_info.zerofill && (max_length != min_length)) ||
(was_zero_fill && (max_length != min_length)))
can_be_still_num = 0; // zerofilled numbers must be of same length
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 7cb05d6bd3c..2eb32d16bb7 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -167,6 +167,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token CACHE_SYM
%token CASCADE
%token CAST_SYM
+%token CHARSET
%token CHECKSUM_SYM
%token CHECK_SYM
%token COMMITTED_SYM
@@ -855,6 +856,8 @@ create_table_option:
table_list->next=0;
lex->create_info.used_fields|= HA_CREATE_USED_UNION;
}
+ | CHARSET opt_equal ident {}
+ | CHAR_SYM SET opt_equal ident {}
| INSERT_METHOD EQ merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;}
| DATA_SYM DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.data_file_name= $4.str; }
| INDEX DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.index_file_name= $4.str; };
@@ -1088,6 +1091,7 @@ attribute:
opt_binary:
/* empty */ {}
| BINARY { Lex->type|=BINARY_FLAG; };
+ | CHAR_SYM SET opt_equal ident {}
references:
REFERENCES table_ident opt_on_delete {}
@@ -3192,6 +3196,7 @@ keyword:
| BOOLEAN_SYM {}
| CACHE_SYM {}
| CHANGED {}
+ | CHARSET {}
| CHECKSUM_SYM {}
| CIPHER_SYM {}
| CLIENT_SYM {}