mirror of
https://github.com/MariaDB/server.git
synced 2025-02-01 11:31:51 +01:00
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.1-new
into poseidon.ndb.mysql.com:/home/tomas/mysql-5.1-new
This commit is contained in:
commit
0e8ccc1bee
17 changed files with 266 additions and 77 deletions
|
@ -3580,7 +3580,7 @@ sub valgrind_arguments {
|
|||
|
||||
if ( $opt_valgrind_options )
|
||||
{
|
||||
mtr_add_arg($args, split(' ', $opt_valgrind_options));
|
||||
mtr_add_arg($args, '%s', $_) for (split(' ', $opt_valgrind_options));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -175,6 +175,14 @@ SELECT CASE '1' WHEN '2' THEN 'BUG' ELSE 'nobug' END;
|
|||
case+union+test
|
||||
case+union+test
|
||||
nobug
|
||||
create table t1(a float, b int default 3);
|
||||
insert into t1 (a) values (2), (11), (8);
|
||||
select min(a), min(case when 1=1 then a else NULL end),
|
||||
min(case when 1!=1 then NULL else a end)
|
||||
from t1 where b=3 group by b;
|
||||
min(a) min(case when 1=1 then a else NULL end) min(case when 1!=1 then NULL else a end)
|
||||
2 2 2
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (EMPNUM INT);
|
||||
INSERT INTO t1 VALUES (0), (2);
|
||||
CREATE TABLE t2 (EMPNUM DECIMAL (4, 2));
|
||||
|
|
|
@ -43,7 +43,7 @@ SLEEP(3)
|
|||
0
|
||||
SELECT user_host, query_time, db, sql_text FROM mysql.slow_log;
|
||||
user_host query_time db sql_text
|
||||
root[root] @ localhost [] 00:00:03 events_test SELECT SLEEP(3)
|
||||
root[root] @ localhost [] SLEEPVAL events_test SELECT SLEEP(3)
|
||||
TRUNCATE mysql.slow_log;
|
||||
CREATE TABLE slow_event_test (slo_val tinyint, val tinyint);
|
||||
"This won't go to the slow log"
|
||||
|
@ -75,7 +75,7 @@ slo_val val
|
|||
"Check slow log. Should see 1 row because 5 is over the threshold of 4 for GLOBAL, though under SESSION which is 10"
|
||||
SELECT user_host, query_time, db, sql_text FROM mysql.slow_log;
|
||||
user_host query_time db sql_text
|
||||
root[root] @ localhost [localhost] 00:00:05 events_test INSERT INTO slow_event_test SELECT @@long_query_time, SLEEP(5)
|
||||
root[root] @ localhost [localhost] SLEEPVAL events_test INSERT INTO slow_event_test SELECT @@long_query_time, SLEEP(5)
|
||||
DROP EVENT long_event2;
|
||||
SET GLOBAL long_query_time =@old_global_long_query_time;
|
||||
SET SESSION long_query_time =@old_session_long_query_time;
|
||||
|
|
|
@ -4,7 +4,9 @@ CREATE TABLE table_1(a int);
|
|||
CREATE TABLE table_2(a int);
|
||||
CREATE TABLE table_3(a int);
|
||||
CREATE TABLE table_4(a int);
|
||||
CREATE TABLE T19170(s1 TIMESTAMP);
|
||||
SET GLOBAL event_scheduler=1;
|
||||
CREATE EVENT E19170 ON SCHEDULE EVERY 1 SECOND DO INSERT INTO T19170 VALUES(CURRENT_TIMESTAMP);
|
||||
CREATE EVENT two_sec ON SCHEDULE EVERY 2 SECOND DO INSERT INTO table_1 VALUES(1);
|
||||
CREATE EVENT start_n_end
|
||||
ON SCHEDULE EVERY 1 SECOND
|
||||
|
@ -29,8 +31,8 @@ DROP EVENT two_sec;
|
|||
SELECT IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
|
||||
IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR')
|
||||
OK
|
||||
SELECT IF(LAST_EXECUTED-ENDS < 2, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
|
||||
IF(LAST_EXECUTED-ENDS < 2, 'OK', 'ERROR')
|
||||
SELECT IF(LAST_EXECUTED-ENDS < 3, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
|
||||
IF(LAST_EXECUTED-ENDS < 3, 'OK', 'ERROR')
|
||||
OK
|
||||
DROP EVENT start_n_end;
|
||||
"Already dropped because ended. Therefore an error."
|
||||
|
@ -43,4 +45,8 @@ DROP TABLE table_1;
|
|||
DROP TABLE table_2;
|
||||
DROP TABLE table_3;
|
||||
DROP TABLE table_4;
|
||||
"Checking for multiple executions in one second, should not happen -> 0 as result"
|
||||
SELECT COUNT(*) FROM (SELECT s1, COUNT(*) AS cnt FROM T19170 GROUP BY s1) AS tmp WHERE tmp.cnt > 1;
|
||||
COUNT(*)
|
||||
0
|
||||
DROP DATABASE events_test;
|
||||
|
|
|
@ -72,3 +72,10 @@ set @@max_allowed_packet=1048576*100;
|
|||
select compress(repeat('aaaaaaaaaa', IF(XXX, 10, 10000000))) is null;
|
||||
compress(repeat('aaaaaaaaaa', IF(XXX, 10, 10000000))) is null
|
||||
0
|
||||
create table t1(a blob);
|
||||
insert into t1 values(NULL), (compress('a'));
|
||||
select uncompress(a), uncompressed_length(a) from t1;
|
||||
uncompress(a) uncompressed_length(a)
|
||||
NULL NULL
|
||||
a 1
|
||||
drop table t1;
|
||||
|
|
|
@ -88,3 +88,17 @@ f
|
|||
1
|
||||
drop temporary table t4;
|
||||
drop table t5;
|
||||
set @session.pseudo_thread_id=100;
|
||||
create temporary table t101 (id int);
|
||||
create temporary table t102 (id int);
|
||||
set @session.pseudo_thread_id=200;
|
||||
create temporary table t201 (id int);
|
||||
create temporary table `#not_user_table_prefixed_with_hash_sign_no_harm` (id int);
|
||||
set @con1_id=connection_id();
|
||||
kill @con1_id;
|
||||
create table t1(f int);
|
||||
insert into t1 values (1);
|
||||
select * from t1 /* must be 1 */;
|
||||
f
|
||||
1
|
||||
drop table t1;
|
||||
|
|
|
@ -122,6 +122,17 @@ SELECT 'case+union+test'
|
|||
UNION
|
||||
SELECT CASE '1' WHEN '2' THEN 'BUG' ELSE 'nobug' END;
|
||||
|
||||
#
|
||||
# Bug #17896: problem with MIN(CASE...)
|
||||
#
|
||||
|
||||
create table t1(a float, b int default 3);
|
||||
insert into t1 (a) values (2), (11), (8);
|
||||
select min(a), min(case when 1=1 then a else NULL end),
|
||||
min(case when 1!=1 then NULL else a end)
|
||||
from t1 where b=3 group by b;
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
events_bugs : BUG#17619 2006-02-21 andrey Race conditions
|
||||
events_stress : BUG#17619 2006-02-21 andrey Race conditions
|
||||
events : BUG#17619 2006-02-21 andrey Race conditions
|
||||
events_scheduling : BUG#18958 2006-04-13 andrey Test case unstable
|
||||
events_logs_tests : BUG#18953 2006-04-12 kent Test is randomly failing
|
||||
ndb_autodiscover : BUG#18952 2006-02-16 jmiller Needs to be fixed w.r.t binlog
|
||||
ndb_autodiscover2 : BUG#18952 2006-02-16 jmiller Needs to be fixed w.r.t binlog
|
||||
#ndb_cache2 : BUG#18597 2006-03-28 brian simultaneous drop table and ndb statistics update triggers node failure
|
||||
|
|
|
@ -56,6 +56,7 @@ SET GLOBAL long_query_time=4;
|
|||
SET SESSION long_query_time=2;
|
||||
--echo "Check that logging is working"
|
||||
SELECT SLEEP(3);
|
||||
--replace_regex /00:00:0[3-5]/SLEEPVAL/
|
||||
SELECT user_host, query_time, db, sql_text FROM mysql.slow_log;
|
||||
TRUNCATE mysql.slow_log;
|
||||
CREATE TABLE slow_event_test (slo_val tinyint, val tinyint);
|
||||
|
@ -79,6 +80,7 @@ CREATE EVENT long_event2 ON SCHEDULE EVERY 1 MINUTE DO INSERT INTO slow_event_te
|
|||
--echo "Check our table. Should see 2 rows"
|
||||
SELECT * FROM slow_event_test;
|
||||
--echo "Check slow log. Should see 1 row because 5 is over the threshold of 4 for GLOBAL, though under SESSION which is 10"
|
||||
--replace_regex /00:00:0[5-7]/SLEEPVAL/
|
||||
SELECT user_host, query_time, db, sql_text FROM mysql.slow_log;
|
||||
DROP EVENT long_event2;
|
||||
SET GLOBAL long_query_time =@old_global_long_query_time;
|
||||
|
|
|
@ -4,7 +4,9 @@ CREATE TABLE table_1(a int);
|
|||
CREATE TABLE table_2(a int);
|
||||
CREATE TABLE table_3(a int);
|
||||
CREATE TABLE table_4(a int);
|
||||
CREATE TABLE T19170(s1 TIMESTAMP);
|
||||
SET GLOBAL event_scheduler=1;
|
||||
CREATE EVENT E19170 ON SCHEDULE EVERY 1 SECOND DO INSERT INTO T19170 VALUES(CURRENT_TIMESTAMP);
|
||||
CREATE EVENT two_sec ON SCHEDULE EVERY 2 SECOND DO INSERT INTO table_1 VALUES(1);
|
||||
CREATE EVENT start_n_end
|
||||
ON SCHEDULE EVERY 1 SECOND
|
||||
|
@ -21,7 +23,7 @@ SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_3;
|
|||
SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_4;
|
||||
DROP EVENT two_sec;
|
||||
SELECT IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
|
||||
SELECT IF(LAST_EXECUTED-ENDS < 2, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
|
||||
SELECT IF(LAST_EXECUTED-ENDS < 3, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
|
||||
DROP EVENT start_n_end;
|
||||
--echo "Already dropped because ended. Therefore an error."
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
|
@ -33,4 +35,6 @@ DROP TABLE table_1;
|
|||
DROP TABLE table_2;
|
||||
DROP TABLE table_3;
|
||||
DROP TABLE table_4;
|
||||
--echo "Checking for multiple executions in one second, should not happen -> 0 as result"
|
||||
SELECT COUNT(*) FROM (SELECT s1, COUNT(*) AS cnt FROM T19170 GROUP BY s1) AS tmp WHERE tmp.cnt > 1;
|
||||
DROP DATABASE events_test;
|
||||
|
|
|
@ -47,4 +47,13 @@ set @@max_allowed_packet=1048576*100;
|
|||
--replace_result "''" XXX "'1'" XXX
|
||||
eval select compress(repeat('aaaaaaaaaa', IF('$LOW_MEMORY', 10, 10000000))) is null;
|
||||
|
||||
#
|
||||
# Bug #18643: problem with null values
|
||||
#
|
||||
|
||||
create table t1(a blob);
|
||||
insert into t1 values(NULL), (compress('a'));
|
||||
select uncompress(a), uncompressed_length(a) from t1;
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
|
|
@ -131,6 +131,8 @@ drop table t1,t2;
|
|||
create temporary table t3 (f int);
|
||||
sync_with_master;
|
||||
|
||||
# The server will now close done
|
||||
|
||||
#
|
||||
# Bug#17284 erroneous temp table cleanup on slave
|
||||
#
|
||||
|
@ -156,5 +158,31 @@ connection master;
|
|||
drop temporary table t4;
|
||||
drop table t5;
|
||||
|
||||
# The server will now close done
|
||||
#
|
||||
# BUG#17263 incorrect generation DROP temp tables
|
||||
# Temporary tables of connection are dropped in batches
|
||||
# where a batch correspond to pseudo_thread_id
|
||||
# value was set up at the moment of temp table creation
|
||||
#
|
||||
connection con1;
|
||||
set @session.pseudo_thread_id=100;
|
||||
create temporary table t101 (id int);
|
||||
create temporary table t102 (id int);
|
||||
set @session.pseudo_thread_id=200;
|
||||
create temporary table t201 (id int);
|
||||
create temporary table `#not_user_table_prefixed_with_hash_sign_no_harm` (id int);
|
||||
set @con1_id=connection_id();
|
||||
kill @con1_id;
|
||||
|
||||
#now do something to show that slave is ok after DROP temp tables
|
||||
connection master;
|
||||
create table t1(f int);
|
||||
insert into t1 values (1);
|
||||
|
||||
sync_slave_with_master;
|
||||
#connection slave;
|
||||
select * from t1 /* must be 1 */;
|
||||
|
||||
connection master;
|
||||
drop table t1;
|
||||
# End of 5.1 tests
|
||||
|
|
|
@ -731,7 +731,9 @@ bool get_next_time(TIME *next, TIME *start, TIME *time_now, TIME *last_exec,
|
|||
get the next exec if the modulus is not
|
||||
*/
|
||||
DBUG_PRINT("info", ("multiplier=%d", multiplier));
|
||||
if (seconds_diff % seconds || (!seconds_diff && last_exec->year))
|
||||
if (seconds_diff % seconds || (!seconds_diff && last_exec->year) ||
|
||||
TIME_to_ulonglong_datetime(time_now) ==
|
||||
TIME_to_ulonglong_datetime(last_exec))
|
||||
++multiplier;
|
||||
interval.second= seconds * multiplier;
|
||||
DBUG_PRINT("info", ("multiplier=%u interval.second=%u", multiplier,
|
||||
|
@ -893,16 +895,15 @@ Event_timed::compute_next_execution_time()
|
|||
DBUG_PRINT("info", ("Both STARTS & ENDS are set"));
|
||||
if (!last_executed.year)
|
||||
{
|
||||
DBUG_PRINT("info", ("Not executed so far. Execute NOW."));
|
||||
execute_at= time_now;
|
||||
execute_at_null= FALSE;
|
||||
DBUG_PRINT("info", ("Not executed so far."));
|
||||
}
|
||||
else
|
||||
|
||||
{
|
||||
TIME next_exec;
|
||||
|
||||
DBUG_PRINT("info", ("Executed at least once"));
|
||||
if (get_next_time(&next_exec, &starts, &time_now, &last_executed,
|
||||
if (get_next_time(&next_exec, &starts, &time_now,
|
||||
last_executed.year? &last_executed:&starts,
|
||||
expression, interval))
|
||||
goto err;
|
||||
|
||||
|
@ -925,8 +926,9 @@ Event_timed::compute_next_execution_time()
|
|||
}
|
||||
goto ret;
|
||||
}
|
||||
else if (starts_null && ends_null)
|
||||
else if (starts_null && ends_null)
|
||||
{
|
||||
/* starts is always set, so this is a dead branch !! */
|
||||
DBUG_PRINT("info", ("Neither STARTS nor ENDS are set"));
|
||||
/*
|
||||
Both starts and m_ends are not set, so we schedule for the next
|
||||
|
@ -961,25 +963,26 @@ Event_timed::compute_next_execution_time()
|
|||
Hence schedule for starts + m_expression in case last_executed
|
||||
is not set, otherwise to last_executed + m_expression
|
||||
*/
|
||||
if (last_executed.year)
|
||||
if (!last_executed.year)
|
||||
{
|
||||
DBUG_PRINT("info", ("Not executed so far."));
|
||||
}
|
||||
|
||||
{
|
||||
TIME next_exec;
|
||||
DBUG_PRINT("info", ("Executed at least once."));
|
||||
if (get_next_time(&next_exec, &starts, &time_now, &last_executed,
|
||||
if (get_next_time(&next_exec, &starts, &time_now,
|
||||
last_executed.year? &last_executed:&starts,
|
||||
expression, interval))
|
||||
goto err;
|
||||
execute_at= next_exec;
|
||||
DBUG_PRINT("info",("Next[%llu]",TIME_to_ulonglong_datetime(&next_exec)));
|
||||
}
|
||||
else
|
||||
{
|
||||
DBUG_PRINT("info", ("Not executed so far. Execute at STARTS"));
|
||||
execute_at= starts;
|
||||
}
|
||||
execute_at_null= FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this is a dead branch, because starts is always set !!! */
|
||||
DBUG_PRINT("info", ("STARTS is not set. ENDS is set"));
|
||||
/*
|
||||
- m_ends is set
|
||||
|
|
|
@ -41,10 +41,25 @@ static Item_result item_store_type(Item_result a,Item_result b)
|
|||
|
||||
static void agg_result_type(Item_result *type, Item **items, uint nitems)
|
||||
{
|
||||
uint i;
|
||||
type[0]= items[0]->result_type();
|
||||
for (i=1 ; i < nitems ; i++)
|
||||
type[0]= item_store_type(type[0], items[i]->result_type());
|
||||
Item **item, **item_end;
|
||||
|
||||
*type= STRING_RESULT;
|
||||
/* Skip beginning NULL items */
|
||||
for (item= items, item_end= item + nitems; item < item_end; item++)
|
||||
{
|
||||
if ((*item)->type() != Item::NULL_ITEM)
|
||||
{
|
||||
*type= (*item)->result_type();
|
||||
item++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Combine result types. Note: NULL items don't affect the result */
|
||||
for (; item < item_end; item++)
|
||||
{
|
||||
if ((*item)->type() != Item::NULL_ITEM)
|
||||
*type= item_store_type(type[0], (*item)->result_type());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2941,6 +2941,7 @@ String *Item_func_uncompress::val_str(String *str)
|
|||
|
||||
if (!res)
|
||||
goto err;
|
||||
null_value= 0;
|
||||
if (res->is_empty())
|
||||
return res;
|
||||
|
||||
|
|
167
sql/sql_base.cc
167
sql/sql_base.cc
|
@ -1167,16 +1167,26 @@ bool close_thread_table(THD *thd, TABLE **table_ptr)
|
|||
}
|
||||
|
||||
|
||||
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
|
||||
static inline uint tmpkeyval(THD *thd, TABLE *table)
|
||||
{
|
||||
return uint4korr(table->s->table_cache_key.str + table->s->table_cache_key.length - 4);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
|
||||
creates one DROP TEMPORARY TABLE binlog event for each pseudo-thread
|
||||
*/
|
||||
|
||||
void close_temporary_tables(THD *thd)
|
||||
{
|
||||
TABLE *table,*next;
|
||||
char *query, *end;
|
||||
uint query_buf_size;
|
||||
bool found_user_tables = 0;
|
||||
TABLE *next,
|
||||
*prev_table /* prev link is not maintained in TABLE's double-linked list */,
|
||||
*table;
|
||||
char *query= (gptr) 0, *end;
|
||||
uint query_buf_size, max_names_len;
|
||||
bool found_user_tables;
|
||||
|
||||
if (!thd->temporary_tables)
|
||||
return;
|
||||
|
@ -1184,50 +1194,123 @@ void close_temporary_tables(THD *thd)
|
|||
LINT_INIT(end);
|
||||
query_buf_size= 50; // Enough for DROP ... TABLE IF EXISTS
|
||||
|
||||
for (table=thd->temporary_tables ; table ; table=table->next)
|
||||
/*
|
||||
insertion sort of temp tables by pseudo_thread_id to build ordered list
|
||||
of sublists of equal pseudo_thread_id
|
||||
*/
|
||||
for (prev_table= thd->temporary_tables,
|
||||
table= prev_table->next,
|
||||
found_user_tables= (prev_table->s->table_name.str[0] != '#');
|
||||
table;
|
||||
prev_table= table, table= table->next)
|
||||
{
|
||||
TABLE *prev_sorted /* same as for prev_table */,
|
||||
*sorted;
|
||||
/*
|
||||
We are going to add 4 ` around the db/table names, so 1 does not look
|
||||
enough; indeed it is enough, because table->table_cache_key.length is
|
||||
greater (by 8, because of server_id and thread_id) than db||table.
|
||||
table not created directly by the user is moved to the tail.
|
||||
Fixme/todo: nothing (I checked the manual) prevents user to create temp
|
||||
with `#'
|
||||
*/
|
||||
query_buf_size+= table->s->table_cache_key.length+1;
|
||||
}
|
||||
|
||||
if ((query = alloc_root(thd->mem_root, query_buf_size)))
|
||||
// Better add "if exists", in case a RESET MASTER has been done
|
||||
end=strmov(query, "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ");
|
||||
|
||||
for (table=thd->temporary_tables ; table ; table=next)
|
||||
{
|
||||
if (query) // we might be out of memory, but this is not fatal
|
||||
if (table->s->table_name.str[0] == '#')
|
||||
continue;
|
||||
else
|
||||
{
|
||||
// skip temporary tables not created directly by the user
|
||||
if (table->s->table_name.str[0] != '#')
|
||||
found_user_tables = 1;
|
||||
end= strxmov(end, "`",table->s->db.str, "`.`",
|
||||
table->s->table_name.str, "`,", NullS);
|
||||
found_user_tables = 1;
|
||||
}
|
||||
next=table->next;
|
||||
close_temporary(table, 1, 1);
|
||||
}
|
||||
if (query && found_user_tables && mysql_bin_log.is_open() &&
|
||||
!thd->current_stmt_binlog_row_based) // CREATE TEMP TABLE not binlogged if row-based
|
||||
for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table;
|
||||
prev_sorted= sorted, sorted= sorted->next)
|
||||
{
|
||||
if (sorted->s->table_name.str[0] == '#' || tmpkeyval(thd, sorted) > tmpkeyval(thd, table))
|
||||
{
|
||||
/* move into the sorted part of the list from the unsorted */
|
||||
prev_table->next= table->next;
|
||||
table->next= sorted;
|
||||
if (prev_sorted)
|
||||
{
|
||||
prev_sorted->next= table;
|
||||
}
|
||||
else
|
||||
{
|
||||
thd->temporary_tables= table;
|
||||
}
|
||||
table= prev_table;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
calc query_buf_size as max per sublists, one sublist per pseudo thread id.
|
||||
Also stop at first occurence of `#'-named table that starts
|
||||
all implicitly created temp tables
|
||||
*/
|
||||
for (max_names_len= 0, table=thd->temporary_tables;
|
||||
table && table->s->table_name.str[0] != '#';
|
||||
table=table->next)
|
||||
{
|
||||
/* The -1 is to remove last ',' */
|
||||
thd->clear_error();
|
||||
Query_log_event qinfo(thd, query, (ulong)(end-query)-1, 0, FALSE);
|
||||
/*
|
||||
Imagine the thread had created a temp table, then was doing a SELECT, and
|
||||
the SELECT was killed. Then it's not clever to mark the statement above
|
||||
as "killed", because it's not really a statement updating data, and there
|
||||
are 99.99% chances it will succeed on slave.
|
||||
If a real update (one updating a persistent table) was killed on the
|
||||
master, then this real update will be logged with error_code=killed,
|
||||
rightfully causing the slave to stop.
|
||||
*/
|
||||
qinfo.error_code= 0;
|
||||
mysql_bin_log.write(&qinfo);
|
||||
uint tmp_names_len;
|
||||
for (tmp_names_len= table->s->table_cache_key.length + 1;
|
||||
table->next && table->s->table_name.str[0] != '#' &&
|
||||
tmpkeyval(thd, table) == tmpkeyval(thd, table->next);
|
||||
table=table->next)
|
||||
{
|
||||
/*
|
||||
We are going to add 4 ` around the db/table names, so 1 might not look
|
||||
enough; indeed it is enough, because table->s->table_cache_key.length is
|
||||
greater (by 8, because of server_id and thread_id) than db||table.
|
||||
*/
|
||||
tmp_names_len += table->next->s->table_cache_key.length + 1;
|
||||
}
|
||||
if (tmp_names_len > max_names_len) max_names_len= tmp_names_len;
|
||||
}
|
||||
|
||||
/* allocate */
|
||||
if (found_user_tables && mysql_bin_log.is_open() &&
|
||||
!thd->current_stmt_binlog_row_based &&
|
||||
(query = alloc_root(thd->mem_root, query_buf_size+= max_names_len)))
|
||||
// Better add "if exists", in case a RESET MASTER has been done
|
||||
end= strmov(query, "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ");
|
||||
|
||||
/* scan sorted tmps to generate sequence of DROP */
|
||||
for (table=thd->temporary_tables; table; table= next)
|
||||
{
|
||||
if (query // we might be out of memory, but this is not fatal
|
||||
&& table->s->table_name.str[0] != '#')
|
||||
{
|
||||
char *end_cur;
|
||||
/* Set pseudo_thread_id to be that of the processed table */
|
||||
thd->variables.pseudo_thread_id= tmpkeyval(thd, table);
|
||||
/* Loop forward through all tables within the sublist of
|
||||
common pseudo_thread_id to create single DROP query */
|
||||
for (end_cur= end;
|
||||
table && table->s->table_name.str[0] != '#' &&
|
||||
tmpkeyval(thd, table) == thd->variables.pseudo_thread_id;
|
||||
table= next)
|
||||
{
|
||||
end_cur= strxmov(end_cur, "`", table->s->db.str, "`.`",
|
||||
table->s->table_name.str, "`,", NullS);
|
||||
next= table->next;
|
||||
close_temporary(table, 1, 1);
|
||||
}
|
||||
thd->clear_error();
|
||||
/* The -1 is to remove last ',' */
|
||||
Query_log_event qinfo(thd, query, (ulong)(end_cur - query) - 1, 0, FALSE);
|
||||
/*
|
||||
Imagine the thread had created a temp table, then was doing a SELECT,
|
||||
and the SELECT was killed. Then it's not clever to mark the statement
|
||||
above as "killed", because it's not really a statement updating data,
|
||||
and there are 99.99% chances it will succeed on slave. If a real update
|
||||
(one updating a persistent table) was killed on the master, then this
|
||||
real update will be logged with error_code=killed, rightfully causing
|
||||
the slave to stop.
|
||||
*/
|
||||
qinfo.error_code= 0;
|
||||
mysql_bin_log.write(&qinfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
next= table->next;
|
||||
close_temporary(table, 1, 1);
|
||||
}
|
||||
}
|
||||
thd->temporary_tables=0;
|
||||
}
|
||||
|
|
|
@ -34,20 +34,20 @@ static uint lengths[256];
|
|||
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
{"help", 'h', "Display help and exit.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"help", '?', "Synonym for -h.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"count", 'c', "Calculate per-word stats (counts and global weights).",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"dump", 'd', "Dump index (incl. data offsets and word weights).",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"length", 'l', "Report length distribution.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"stats", 's', "Report global stats.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"verbose", 'v', "Be verbose.",
|
||||
(gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"count", 'c', "Calculate per-word stats (counts and global weights).",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"length", 'l', "Report length distribution.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"help", 'h', "Display help and exit.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"help", '?', "Synonym for -h.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue