mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge pgalbraith@bk-internal.mysql.com:/home/bk/mysql-5.0
into radha.local:/Users/patg/mysql-build/mysql-5.0.bug9056
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
drop table if exists t1,t2;
|
||||
show tables;
|
||||
Tables_in_mysql
|
||||
columns_priv
|
||||
@@ -71,3 +72,8 @@ show tables;
|
||||
Tables_in_test
|
||||
delete from mysql.user where user=_binary"test";
|
||||
flush privileges;
|
||||
create table t1 (id integer not null auto_increment primary key);
|
||||
create temporary table t2(id integer not null auto_increment primary key);
|
||||
set @id := 1;
|
||||
delete from t1 where id like @id;
|
||||
drop table t1;
|
||||
|
@@ -766,6 +766,15 @@ n
|
||||
Warnings:
|
||||
Warning 1052 Column 'n' in group statement is ambiguous
|
||||
DROP TABLE t1;
|
||||
create table t1(f1 varchar(5) key);
|
||||
insert into t1 values (1),(2);
|
||||
select sql_buffer_result max(f1) is null from t1;
|
||||
max(f1) is null
|
||||
0
|
||||
select sql_buffer_result max(f1)+1 from t1;
|
||||
max(f1)+1
|
||||
3
|
||||
drop table t1;
|
||||
create table t1 (c1 char(3), c2 char(3));
|
||||
create table t2 (c3 char(3), c4 char(3));
|
||||
insert into t1 values ('aaa', 'bb1'), ('aaa', 'bb2');
|
||||
|
@@ -555,6 +555,31 @@ IFNULL(a, 'TEST') COALESCE(b, 'TEST')
|
||||
4 TEST
|
||||
TEST TEST
|
||||
DROP TABLE t1,t2;
|
||||
CREATE TABLE t1 (a INT(10) NOT NULL, b INT(10) NOT NULL);
|
||||
INSERT INTO t1 VALUES (1, 1);
|
||||
INSERT INTO t1 VALUES (1, 2);
|
||||
SELECT a, b, a AS c, COUNT(*) AS count FROM t1 GROUP BY a, b, c WITH ROLLUP;
|
||||
a b c count
|
||||
1 1 1 1
|
||||
1 1 NULL 1
|
||||
1 2 1 1
|
||||
1 2 NULL 1
|
||||
1 NULL NULL 2
|
||||
NULL NULL NULL 2
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a int(11) NOT NULL);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
SELECT * FROM (SELECT a, a + 1, COUNT(*) FROM t1 GROUP BY a WITH ROLLUP) t;
|
||||
a a + 1 COUNT(*)
|
||||
1 2 1
|
||||
2 3 1
|
||||
NULL NULL 2
|
||||
SELECT * FROM (SELECT a, LENGTH(a), COUNT(*) FROM t1 GROUP BY a WITH ROLLUP) t;
|
||||
a LENGTH(a) COUNT(*)
|
||||
1 1 1
|
||||
2 1 1
|
||||
NULL NULL 2
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(id int, type char(1));
|
||||
INSERT INTO t1 VALUES
|
||||
(1,"A"),(2,"C"),(3,"A"),(4,"A"),(5,"B"),
|
||||
@@ -577,15 +602,19 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using filesort
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a INT(10) NOT NULL, b INT(10) NOT NULL);
|
||||
INSERT INTO t1 VALUES (1, 1);
|
||||
INSERT INTO t1 VALUES (1, 2);
|
||||
SELECT a, b, a AS c, COUNT(*) AS count FROM t1 GROUP BY a, b, c WITH ROLLUP;
|
||||
a b c count
|
||||
1 1 1 1
|
||||
1 1 NULL 1
|
||||
1 2 1 1
|
||||
1 2 NULL 1
|
||||
1 NULL NULL 2
|
||||
NULL NULL NULL 2
|
||||
CREATE TABLE t1 (a int(11) NOT NULL);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
CREATE VIEW v1 AS
|
||||
SELECT a, LENGTH(a), COUNT(*) FROM t1 GROUP BY a WITH ROLLUP;
|
||||
DESC v1;
|
||||
Field Type Null Key Default Extra
|
||||
a bigint(11) YES NULL
|
||||
LENGTH(a) bigint(10) YES NULL
|
||||
COUNT(*) bigint(21) NO 0
|
||||
SELECT * FROM v1;
|
||||
a LENGTH(a) COUNT(*)
|
||||
1 1 1
|
||||
2 1 1
|
||||
NULL NULL 2
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
|
@@ -773,6 +773,14 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
|
||||
select ? from t1;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? from t1' at line 1
|
||||
drop table t1;
|
||||
CREATE TABLE b12651_T1(a int) ENGINE=MYISAM;
|
||||
CREATE TABLE b12651_T2(b int) ENGINE=MYISAM;
|
||||
CREATE VIEW b12651_V1 as SELECT b FROM b12651_T2;
|
||||
PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)';
|
||||
EXECUTE b12651;
|
||||
1
|
||||
DROP VIEW b12651_V1;
|
||||
DROP TABLE b12651_T1, b12651_T2;
|
||||
prepare stmt from "select @@time_zone";
|
||||
execute stmt;
|
||||
@@time_zone
|
||||
|
@@ -156,3 +156,60 @@ slave: 6
|
||||
drop procedure p1;
|
||||
drop function f1;
|
||||
drop table t1,t2;
|
||||
create table t1 (a int);
|
||||
create procedure p1()
|
||||
begin
|
||||
insert into t1 values(@x);
|
||||
set @x=@x+1;
|
||||
insert into t1 values(@x);
|
||||
if (f2()) then
|
||||
insert into t1 values(1243);
|
||||
end if;
|
||||
end//
|
||||
create function f2() returns int
|
||||
begin
|
||||
insert into t1 values(@z);
|
||||
set @z=@z+1;
|
||||
insert into t1 values(@z);
|
||||
return 0;
|
||||
end//
|
||||
create function f1() returns int
|
||||
begin
|
||||
insert into t1 values(@y);
|
||||
call p1();
|
||||
return 0;
|
||||
end//
|
||||
set @x=10;
|
||||
set @y=20;
|
||||
set @z=100;
|
||||
select f1();
|
||||
f1()
|
||||
0
|
||||
set @x=30;
|
||||
call p1();
|
||||
select 'master', a from t1;
|
||||
master a
|
||||
master 20
|
||||
master 10
|
||||
master 11
|
||||
master 100
|
||||
master 101
|
||||
master 30
|
||||
master 31
|
||||
master 101
|
||||
master 102
|
||||
select 'slave', a from t1;
|
||||
slave a
|
||||
slave 20
|
||||
slave 10
|
||||
slave 11
|
||||
slave 100
|
||||
slave 101
|
||||
slave 30
|
||||
slave 31
|
||||
slave 101
|
||||
slave 102
|
||||
drop table t1;
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
drop procedure p1;
|
||||
|
@@ -3085,6 +3085,19 @@ column_name bug10055(t.column_name)
|
||||
id id
|
||||
data data
|
||||
drop function bug10055|
|
||||
drop procedure if exists bug12297|
|
||||
create procedure bug12297(lim int)
|
||||
begin
|
||||
set @x = 0;
|
||||
repeat
|
||||
insert into t1(id,data)
|
||||
values('aa', @x);
|
||||
set @x = @x + 1;
|
||||
until @x >= lim
|
||||
end repeat;
|
||||
end|
|
||||
call bug12297(10)|
|
||||
drop procedure bug12297|
|
||||
drop function if exists f_bug11247|
|
||||
drop procedure if exists p_bug11247|
|
||||
create function f_bug11247(param int)
|
||||
|
@@ -6,6 +6,10 @@
|
||||
# This test makes no sense with the embedded server
|
||||
--source include/not_embedded.inc
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1,t2;
|
||||
--enable_warnings
|
||||
|
||||
#connect (con1,localhost,root,,"");
|
||||
#show tables;
|
||||
connect (con1,localhost,root,,mysql);
|
||||
@@ -77,4 +81,18 @@ show tables;
|
||||
delete from mysql.user where user=_binary"test";
|
||||
flush privileges;
|
||||
|
||||
#
|
||||
# Bug#12517: Clear user variables and replication events before
|
||||
# closing temp tables in thread cleanup.
|
||||
connect (con2,localhost,root,,test);
|
||||
connection con2;
|
||||
create table t1 (id integer not null auto_increment primary key);
|
||||
create temporary table t2(id integer not null auto_increment primary key);
|
||||
set @id := 1;
|
||||
delete from t1 where id like @id;
|
||||
disconnect con2;
|
||||
--sleep 5
|
||||
connection default;
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@@ -580,7 +580,6 @@ SELECT COUNT(DISTINCT(t1.id)), LEFT(err_comment, 256) AS comment
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
|
||||
#
|
||||
# Bug #12266 GROUP BY expression on DATE column produces result with
|
||||
# reduced length
|
||||
@@ -602,6 +601,16 @@ SELECT n+1 AS n FROM t1 GROUP BY n;
|
||||
--enable_ps_protocol
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# BUG#12695: Item_func_isnull::update_used_tables
|
||||
# did not update const_item_cache
|
||||
#
|
||||
create table t1(f1 varchar(5) key);
|
||||
insert into t1 values (1),(2);
|
||||
select sql_buffer_result max(f1) is null from t1;
|
||||
select sql_buffer_result max(f1)+1 from t1;
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
|
@@ -250,6 +250,32 @@ SELECT IFNULL(a, 'TEST'), COALESCE(b, 'TEST') FROM t2
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
#
|
||||
# Test for bug #11543: ROLLUP query with a repeated column in GROUP BY
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (a INT(10) NOT NULL, b INT(10) NOT NULL);
|
||||
INSERT INTO t1 VALUES (1, 1);
|
||||
INSERT INTO t1 VALUES (1, 2);
|
||||
|
||||
SELECT a, b, a AS c, COUNT(*) AS count FROM t1 GROUP BY a, b, c WITH ROLLUP;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
# Bug #12885(1): derived table specified by a subquery with
|
||||
# ROLLUP over expressions on not nullable group by attributes
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (a int(11) NOT NULL);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
|
||||
SELECT * FROM (SELECT a, a + 1, COUNT(*) FROM t1 GROUP BY a WITH ROLLUP) t;
|
||||
SELECT * FROM (SELECT a, LENGTH(a), COUNT(*) FROM t1 GROUP BY a WITH ROLLUP) t;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
# Tests for bug #11639: ROLLUP over view executed through filesort
|
||||
#
|
||||
@@ -266,15 +292,20 @@ EXPLAIN SELECT type FROM v1 GROUP BY type WITH ROLLUP;
|
||||
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
# Test for bug #11543: ROLLUP query with a repeated column in GROUP BY
|
||||
|
||||
#
|
||||
# Bug #12885(2): view specified by a subquery with
|
||||
# ROLLUP over expressions on not nullable group by attributes
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (a INT(10) NOT NULL, b INT(10) NOT NULL);
|
||||
INSERT INTO t1 VALUES (1, 1);
|
||||
INSERT INTO t1 VALUES (1, 2);
|
||||
CREATE TABLE t1 (a int(11) NOT NULL);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
|
||||
SELECT a, b, a AS c, COUNT(*) AS count FROM t1 GROUP BY a, b, c WITH ROLLUP;
|
||||
CREATE VIEW v1 AS
|
||||
SELECT a, LENGTH(a), COUNT(*) FROM t1 GROUP BY a WITH ROLLUP;
|
||||
|
||||
DESC v1;
|
||||
SELECT * FROM v1;
|
||||
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@@ -809,6 +809,21 @@ select ??;
|
||||
select ? from t1;
|
||||
--enable_ps_protocol
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#12651
|
||||
# (Crash on a PS including a subquery which is a select from a simple view)
|
||||
#
|
||||
CREATE TABLE b12651_T1(a int) ENGINE=MYISAM;
|
||||
CREATE TABLE b12651_T2(b int) ENGINE=MYISAM;
|
||||
CREATE VIEW b12651_V1 as SELECT b FROM b12651_T2;
|
||||
|
||||
PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)';
|
||||
EXECUTE b12651;
|
||||
|
||||
DROP VIEW b12651_V1;
|
||||
DROP TABLE b12651_T1, b12651_T2;
|
||||
|
||||
#
|
||||
# Bug#9359 "Prepared statements take snapshot of system vars at PREPARE
|
||||
# time"
|
||||
|
@@ -152,4 +152,52 @@ drop procedure p1;
|
||||
drop function f1;
|
||||
drop table t1,t2;
|
||||
|
||||
# BUG#12637: User variables + SPs replication
|
||||
create table t1 (a int);
|
||||
delimiter //;
|
||||
create procedure p1()
|
||||
begin
|
||||
insert into t1 values(@x);
|
||||
set @x=@x+1;
|
||||
insert into t1 values(@x);
|
||||
if (f2()) then
|
||||
insert into t1 values(1243);
|
||||
end if;
|
||||
end//
|
||||
|
||||
create function f2() returns int
|
||||
begin
|
||||
insert into t1 values(@z);
|
||||
set @z=@z+1;
|
||||
insert into t1 values(@z);
|
||||
return 0;
|
||||
end//
|
||||
|
||||
create function f1() returns int
|
||||
begin
|
||||
insert into t1 values(@y);
|
||||
call p1();
|
||||
return 0;
|
||||
end//
|
||||
|
||||
delimiter ;//
|
||||
|
||||
set @x=10;
|
||||
set @y=20;
|
||||
set @z=100;
|
||||
select f1();
|
||||
|
||||
set @x=30;
|
||||
call p1();
|
||||
|
||||
select 'master', a from t1;
|
||||
sync_slave_with_master;
|
||||
connection slave;
|
||||
select 'slave', a from t1;
|
||||
|
||||
connection master;
|
||||
drop table t1;
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
drop procedure p1;
|
||||
sync_slave_with_master;
|
||||
|
@@ -3877,29 +3877,23 @@ drop function bug10055|
|
||||
# consumption by passing large input parameter.
|
||||
#
|
||||
|
||||
#
|
||||
# Note: the test is currenly disabled because of the
|
||||
# Bug #12637: SP crashes the server if it has update query with user var
|
||||
# & binlog is enabled.
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
#drop procedure if exists bug12297|
|
||||
drop procedure if exists bug12297|
|
||||
--enable_warnings
|
||||
|
||||
#create procedure bug12297(lim int)
|
||||
#begin
|
||||
# set @x = 0;
|
||||
# repeat
|
||||
# insert into t1(id,data)
|
||||
# values('aa', @x);
|
||||
# set @x = @x + 1;
|
||||
# until @x >= lim
|
||||
# end repeat;
|
||||
#end|
|
||||
create procedure bug12297(lim int)
|
||||
begin
|
||||
set @x = 0;
|
||||
repeat
|
||||
insert into t1(id,data)
|
||||
values('aa', @x);
|
||||
set @x = @x + 1;
|
||||
until @x >= lim
|
||||
end repeat;
|
||||
end|
|
||||
|
||||
#call bug12297(10)|
|
||||
#drop procedure bug12297|
|
||||
call bug12297(10)|
|
||||
drop procedure bug12297|
|
||||
|
||||
#
|
||||
# Bug #11247 "Stored procedures: Function calls in long loops leak memory"
|
||||
|
@@ -266,5 +266,4 @@ SignalSender::execNodeStatus(void* signalSender,
|
||||
|
||||
template SimpleSignal* SignalSender::waitFor<WaitForNode>(unsigned, WaitForNode&);
|
||||
template SimpleSignal* SignalSender::waitFor<WaitForAny>(unsigned, WaitForAny&);
|
||||
template Vector<SimpleSignal*>;
|
||||
|
||||
template class Vector<SimpleSignal*>;
|
||||
|
@@ -570,12 +570,20 @@ int ha_prepare(THD *thd)
|
||||
{
|
||||
int err;
|
||||
statistic_increment(thd->status_var.ha_prepare_count,&LOCK_status);
|
||||
if ((err= (*(*ht)->prepare)(thd, all)))
|
||||
if ((*ht)->prepare)
|
||||
{
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
|
||||
ha_rollback_trans(thd, all);
|
||||
error=1;
|
||||
break;
|
||||
if ((err= (*(*ht)->prepare)(thd, all)))
|
||||
{
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
|
||||
ha_rollback_trans(thd, all);
|
||||
error=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), (*ht)->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1169,6 +1169,8 @@ void Item_func_between::print(String *str)
|
||||
{
|
||||
str->append('(');
|
||||
args[0]->print(str);
|
||||
if (negated)
|
||||
str->append(" not", 4);
|
||||
str->append(" between ", 9);
|
||||
args[1]->print(str);
|
||||
str->append(" and ", 5);
|
||||
@@ -2411,6 +2413,8 @@ void Item_func_in::print(String *str)
|
||||
{
|
||||
str->append('(');
|
||||
args[0]->print(str);
|
||||
if (negated)
|
||||
str->append(" not", 4);
|
||||
str->append(" in (", 5);
|
||||
print_args(str, 1);
|
||||
str->append("))", 2);
|
||||
|
@@ -910,7 +910,7 @@ public:
|
||||
else
|
||||
{
|
||||
args[0]->update_used_tables();
|
||||
if (!(used_tables_cache=args[0]->used_tables()))
|
||||
if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())))
|
||||
{
|
||||
/* Remember if the value is always NULL or never NULL */
|
||||
cached_value= (longlong) args[0]->is_null();
|
||||
|
@@ -3884,7 +3884,8 @@ int get_var_with_binlog(THD *thd, enum_sql_command sql_command,
|
||||
if (!(var_entry= get_variable(&thd->user_vars, name, 0)))
|
||||
goto err;
|
||||
}
|
||||
else if (var_entry->used_query_id == thd->query_id)
|
||||
else if (var_entry->used_query_id == thd->query_id ||
|
||||
mysql_bin_log.is_query_in_union(thd, var_entry->used_query_id))
|
||||
{
|
||||
/*
|
||||
If this variable was already stored in user_var_events by this query
|
||||
@@ -3901,10 +3902,16 @@ int get_var_with_binlog(THD *thd, enum_sql_command sql_command,
|
||||
appears:
|
||||
> set @a:=1;
|
||||
> insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1);
|
||||
We have to write to binlog value @a= 1;
|
||||
We have to write to binlog value @a= 1.
|
||||
|
||||
We allocate the user_var_event on user_var_events_alloc pool, not on
|
||||
the this-statement-execution pool because in SPs user_var_event objects
|
||||
may need to be valid after current [SP] statement execution pool is
|
||||
destroyed.
|
||||
*/
|
||||
size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length;
|
||||
if (!(user_var_event= (BINLOG_USER_VAR_EVENT *) thd->alloc(size)))
|
||||
if (!(user_var_event= (BINLOG_USER_VAR_EVENT *)
|
||||
alloc_root(thd->user_var_events_alloc, size)))
|
||||
goto err;
|
||||
|
||||
user_var_event->value= (char*) user_var_event +
|
||||
|
@@ -2743,7 +2743,7 @@ int dump_leaf_key(byte* key, element_count count __attribute__((unused)),
|
||||
if (item->no_appended)
|
||||
item->no_appended= FALSE;
|
||||
else
|
||||
item->result.append(*item->separator);
|
||||
result->append(*item->separator);
|
||||
|
||||
tmp.length(0);
|
||||
|
||||
|
@@ -1559,6 +1559,7 @@ void MYSQL_LOG::start_union_events(THD *thd)
|
||||
thd->binlog_evt_union.do_union= TRUE;
|
||||
thd->binlog_evt_union.unioned_events= FALSE;
|
||||
thd->binlog_evt_union.unioned_events_trans= FALSE;
|
||||
thd->binlog_evt_union.first_query_id= thd->query_id;
|
||||
}
|
||||
|
||||
void MYSQL_LOG::stop_union_events(THD *thd)
|
||||
@@ -1567,6 +1568,12 @@ void MYSQL_LOG::stop_union_events(THD *thd)
|
||||
thd->binlog_evt_union.do_union= FALSE;
|
||||
}
|
||||
|
||||
bool MYSQL_LOG::is_query_in_union(THD *thd, query_id_t query_id_param)
|
||||
{
|
||||
return (thd->binlog_evt_union.do_union &&
|
||||
query_id_param >= thd->binlog_evt_union.first_query_id);
|
||||
}
|
||||
|
||||
/*
|
||||
Write an event to the binary log
|
||||
*/
|
||||
|
@@ -689,10 +689,35 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
|
||||
* If this function invocation is done from a statement that is written
|
||||
into the binary log.
|
||||
* If there were any attempts to write events to the binary log during
|
||||
function execution.
|
||||
function execution (grep for start_union_events and stop_union_events)
|
||||
|
||||
If the answers are No and Yes, we write the function call into the binary
|
||||
log as "DO spfunc(<param1value>, <param2value>, ...)"
|
||||
|
||||
|
||||
4. Miscellaneous issues.
|
||||
|
||||
4.1 User variables.
|
||||
|
||||
When we call mysql_bin_log.write() for an SP statement, thd->user_var_events
|
||||
must hold set<{var_name, value}> pairs for all user variables used during
|
||||
the statement execution.
|
||||
This set is produced by tracking user variable reads during statement
|
||||
execution.
|
||||
|
||||
Fo SPs, this has the following implications:
|
||||
1) thd->user_var_events may contain events from several SP statements and
|
||||
needs to be valid after exection of these statements was finished. In
|
||||
order to achieve that, we
|
||||
* Allocate user_var_events array elements on appropriate mem_root (grep
|
||||
for user_var_events_alloc).
|
||||
* Use is_query_in_union() to determine if user_var_event is created.
|
||||
|
||||
2) We need to empty thd->user_var_events after we have wrote a function
|
||||
call. This is currently done by making
|
||||
reset_dynamic(&thd->user_var_events);
|
||||
calls in several different places. (TODO cosider moving this into
|
||||
mysql_bin_log.write() function)
|
||||
*/
|
||||
|
||||
|
||||
@@ -908,6 +933,7 @@ int sp_head::execute(THD *thd)
|
||||
/* Don't change NOW() in FUNCTION or TRIGGER */
|
||||
if (!thd->in_sub_stmt)
|
||||
thd->set_time(); // Make current_time() et al work
|
||||
|
||||
/*
|
||||
We have to set thd->stmt_arena before executing the instruction
|
||||
to store in the instruction free_list all new items, created
|
||||
@@ -915,6 +941,13 @@ int sp_head::execute(THD *thd)
|
||||
items made during other permanent subquery transformations).
|
||||
*/
|
||||
thd->stmt_arena= i;
|
||||
|
||||
/* will binlog this separately */
|
||||
if (thd->prelocked_mode == NON_PRELOCKED) //TODO: change to event union?
|
||||
{
|
||||
thd->user_var_events_alloc= thd->mem_root;
|
||||
}
|
||||
|
||||
ret= i->execute(thd, &ip);
|
||||
|
||||
/*
|
||||
@@ -929,15 +962,6 @@ int sp_head::execute(THD *thd)
|
||||
|
||||
/* we should cleanup free_list and memroot, used by instruction */
|
||||
thd->free_items();
|
||||
/*
|
||||
FIXME: we must free user var events only if the routine is executed
|
||||
in non-prelocked mode and statement-by-statement replication is used.
|
||||
But if we don't free them now, the server crashes because user var
|
||||
events are allocated in execute_mem_root. This is Bug#12637, and when
|
||||
it's fixed, please add if (thd->options & OPTION_BIN_LOG) here.
|
||||
*/
|
||||
if (opt_bin_log)
|
||||
reset_dynamic(&thd->user_var_events);
|
||||
free_root(&execute_mem_root, MYF(0));
|
||||
|
||||
/*
|
||||
@@ -1095,7 +1119,10 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
|
||||
binlog_save_options= thd->options;
|
||||
need_binlog_call= mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG);
|
||||
if (need_binlog_call)
|
||||
{
|
||||
reset_dynamic(&thd->user_var_events);
|
||||
mysql_bin_log.start_union_events(thd);
|
||||
}
|
||||
|
||||
thd->options&= ~OPTION_BIN_LOG;
|
||||
ret= execute(thd);
|
||||
@@ -1129,6 +1156,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
|
||||
"Invoked ROUTINE modified a transactional table but MySQL "
|
||||
"failed to reflect this change in the binary log");
|
||||
}
|
||||
reset_dynamic(&thd->user_var_events);
|
||||
}
|
||||
|
||||
if (m_type == TYPE_ENUM_FUNCTION && ret == 0)
|
||||
|
@@ -108,13 +108,14 @@ class sp_head :private Query_arena
|
||||
MEM_ROOT main_mem_root;
|
||||
public:
|
||||
/* Possible values of m_flags */
|
||||
const static int
|
||||
enum {
|
||||
HAS_RETURN= 1, // For FUNCTIONs only: is set if has RETURN
|
||||
IN_SIMPLE_CASE= 2, // Is set if parsing a simple CASE
|
||||
IN_HANDLER= 4, // Is set if the parser is in a handler body
|
||||
MULTI_RESULTS= 8, // Is set if a procedure with SELECT(s)
|
||||
CONTAINS_DYNAMIC_SQL= 16, // Is set if a procedure with PREPARE/EXECUTE
|
||||
IS_INVOKED= 32; // Is set if this sp_head is being used.
|
||||
IS_INVOKED= 32 // Is set if this sp_head is being used.
|
||||
};
|
||||
|
||||
int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE
|
||||
uint m_flags; // Boolean attributes of a stored routine
|
||||
|
@@ -2612,6 +2612,8 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
|
||||
table_list->alias, name, item_name, (ulong) ref));
|
||||
Field_iterator_view field_it;
|
||||
field_it.set(table_list);
|
||||
Query_arena *arena, backup;
|
||||
|
||||
DBUG_ASSERT(table_list->schema_table_reformed ||
|
||||
(ref != 0 && table_list->view != 0));
|
||||
for (; !field_it.end_of_fields(); field_it.next())
|
||||
@@ -2633,7 +2635,13 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
|
||||
name, length))
|
||||
DBUG_RETURN(WRONG_GRANT);
|
||||
#endif
|
||||
// in PS use own arena or data will be freed after prepare
|
||||
if (register_tree_change)
|
||||
arena= thd->activate_stmt_arena_if_needed(&backup);
|
||||
Item *item= field_it.create_item(thd);
|
||||
if (register_tree_change && arena)
|
||||
thd->restore_active_arena(arena, &backup);
|
||||
|
||||
if (!item)
|
||||
DBUG_RETURN(0);
|
||||
/*
|
||||
@@ -2695,6 +2703,8 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
||||
field_it(*(table_ref->join_columns));
|
||||
Natural_join_column *nj_col;
|
||||
Field *found_field;
|
||||
Query_arena *arena, backup;
|
||||
|
||||
DBUG_ENTER("find_field_in_natural_join");
|
||||
DBUG_PRINT("enter", ("field name: '%s', ref 0x%lx",
|
||||
name, (ulong) ref));
|
||||
@@ -2723,7 +2733,14 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
||||
The found field is a view field, we do as in find_field_in_view()
|
||||
and return a pointer to pointer to the Item of that field.
|
||||
*/
|
||||
if (register_tree_change)
|
||||
arena= thd->activate_stmt_arena_if_needed(&backup);
|
||||
|
||||
Item *item= nj_col->create_item(thd);
|
||||
|
||||
if (register_tree_change && arena)
|
||||
thd->restore_active_arena(arena, &backup);
|
||||
|
||||
if (!item)
|
||||
DBUG_RETURN(NULL);
|
||||
DBUG_ASSERT(nj_col->table_field == NULL);
|
||||
|
@@ -377,14 +377,16 @@ void THD::cleanup(void)
|
||||
mysql_ha_flush(this, (TABLE_LIST*) 0,
|
||||
MYSQL_HA_CLOSE_FINAL | MYSQL_HA_FLUSH_ALL);
|
||||
hash_free(&handler_tables_hash);
|
||||
delete_dynamic(&user_var_events);
|
||||
hash_free(&user_vars);
|
||||
close_temporary_tables(this);
|
||||
my_free((char*) variables.time_format, MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free((char*) variables.date_format, MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free((char*) variables.datetime_format, MYF(MY_ALLOW_ZERO_PTR));
|
||||
delete_dynamic(&user_var_events);
|
||||
hash_free(&user_vars);
|
||||
|
||||
sp_cache_clear(&sp_proc_cache);
|
||||
sp_cache_clear(&sp_func_cache);
|
||||
|
||||
if (global_read_lock)
|
||||
unlock_global_read_lock(this);
|
||||
if (ull)
|
||||
@@ -424,9 +426,6 @@ THD::~THD()
|
||||
|
||||
ha_close_connection(this);
|
||||
|
||||
sp_cache_clear(&sp_proc_cache);
|
||||
sp_cache_clear(&sp_func_cache);
|
||||
|
||||
DBUG_PRINT("info", ("freeing host"));
|
||||
if (host != my_localhost) // If not pointer to constant
|
||||
safeFree(host);
|
||||
|
@@ -313,6 +313,7 @@ public:
|
||||
|
||||
void start_union_events(THD *thd);
|
||||
void stop_union_events(THD *thd);
|
||||
bool is_query_in_union(THD *thd, query_id_t query_id_param);
|
||||
|
||||
/*
|
||||
v stands for vector
|
||||
@@ -1303,8 +1304,9 @@ public:
|
||||
/* variables.transaction_isolation is reset to this after each commit */
|
||||
enum_tx_isolation session_tx_isolation;
|
||||
enum_check_fields count_cuted_fields;
|
||||
/* for user variables replication*/
|
||||
DYNAMIC_ARRAY user_var_events;
|
||||
|
||||
DYNAMIC_ARRAY user_var_events; /* For user variables replication */
|
||||
MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */
|
||||
|
||||
enum killed_state { NOT_KILLED=0, KILL_BAD_DATA=1, KILL_CONNECTION=ER_SERVER_SHUTDOWN, KILL_QUERY=ER_QUERY_INTERRUPTED };
|
||||
killed_state volatile killed;
|
||||
@@ -1366,6 +1368,12 @@ public:
|
||||
mysql_bin_log.start_union_events() call.
|
||||
*/
|
||||
bool unioned_events_trans;
|
||||
|
||||
/*
|
||||
'queries' (actually SP statements) that run under inside this binlog
|
||||
union have thd->query_id >= first_query_id.
|
||||
*/
|
||||
query_id_t first_query_id;
|
||||
} binlog_evt_union;
|
||||
|
||||
THD();
|
||||
|
@@ -2438,6 +2438,12 @@ mysql_execute_command(THD *thd)
|
||||
{
|
||||
if (lex->describe)
|
||||
{
|
||||
/*
|
||||
We always use select_send for EXPLAIN, even if it's an EXPLAIN
|
||||
for SELECT ... INTO OUTFILE: a user application should be able
|
||||
to prepend EXPLAIN to any query and receive output for it,
|
||||
even if the query itself redirects the output.
|
||||
*/
|
||||
if (!(result= new select_send()))
|
||||
goto error;
|
||||
else
|
||||
@@ -5162,7 +5168,10 @@ void mysql_reset_thd_for_next_command(THD *thd)
|
||||
if (!thd->in_sub_stmt)
|
||||
{
|
||||
if (opt_bin_log)
|
||||
{
|
||||
reset_dynamic(&thd->user_var_events);
|
||||
thd->user_var_events_alloc= thd->mem_root;
|
||||
}
|
||||
thd->clear_error();
|
||||
thd->total_warn_count=0; // Warnings for this query
|
||||
thd->rand_used= 0;
|
||||
|
@@ -13043,6 +13043,8 @@ void free_underlaid_joins(THD *thd, SELECT_LEX *select)
|
||||
The function replaces occurrences of group by fields in expr
|
||||
by ref objects for these fields unless they are under aggregate
|
||||
functions.
|
||||
The function also corrects value of the the maybe_null attribute
|
||||
for the items of all subexpressions containing group by fields.
|
||||
|
||||
IMPLEMENTATION
|
||||
The function recursively traverses the tree of the expr expression,
|
||||
@@ -13053,6 +13055,9 @@ void free_underlaid_joins(THD *thd, SELECT_LEX *select)
|
||||
This substitution is needed GROUP BY queries with ROLLUP if
|
||||
SELECT list contains expressions over group by attributes.
|
||||
|
||||
TODO: Some functions are not null-preserving. For those functions
|
||||
updating of the maybe_null attribute is an overkill.
|
||||
|
||||
EXAMPLES
|
||||
SELECT a+1 FROM t1 GROUP BY a WITH ROLLUP
|
||||
SELECT SUM(a)+a FROM t1 GROUP BY a WITH ROLLUP
|
||||
@@ -13074,6 +13079,7 @@ static bool change_group_ref(THD *thd, Item_func *expr, ORDER *group_list,
|
||||
arg != arg_end; arg++)
|
||||
{
|
||||
Item *item= *arg;
|
||||
bool arg_changed= FALSE;
|
||||
if (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM)
|
||||
{
|
||||
ORDER *group_tmp;
|
||||
@@ -13086,15 +13092,20 @@ static bool change_group_ref(THD *thd, Item_func *expr, ORDER *group_list,
|
||||
item->name)))
|
||||
return 1; // fatal_error is set
|
||||
thd->change_item_tree(arg, new_item);
|
||||
*changed= TRUE;
|
||||
arg_changed= TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (item->type() == Item::FUNC_ITEM)
|
||||
{
|
||||
if (change_group_ref(thd, (Item_func *) item, group_list, changed))
|
||||
if (change_group_ref(thd, (Item_func *) item, group_list, &arg_changed))
|
||||
return 1;
|
||||
}
|
||||
if (arg_changed)
|
||||
{
|
||||
expr->maybe_null= 1;
|
||||
*changed= TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -13157,7 +13168,7 @@ bool JOIN::rollup_init()
|
||||
}
|
||||
if (item->type() == Item::FUNC_ITEM)
|
||||
{
|
||||
bool changed= 0;
|
||||
bool changed= FALSE;
|
||||
if (change_group_ref(thd, (Item_func *) item, group_list, &changed))
|
||||
return 1;
|
||||
/*
|
||||
|
@@ -39,7 +39,8 @@
|
||||
# If you want to affect other MySQL variables, you should make your changes
|
||||
# in the /etc/my.cnf, ~/.my.cnf or other MySQL configuration files.
|
||||
|
||||
# If you change base dir, you must also change datadir
|
||||
# If you change base dir, you must also change datadir. These may get
|
||||
# overwritten by settings in the MySQL configuration files.
|
||||
|
||||
basedir=
|
||||
datadir=
|
||||
@@ -61,8 +62,8 @@ then
|
||||
else
|
||||
bindir="$basedir/bin"
|
||||
datadir="$basedir/data"
|
||||
sbindir="$basedir/bin"
|
||||
libexecdir="$basedir/bin"
|
||||
sbindir="$basedir/sbin"
|
||||
libexecdir="$basedir/libexec"
|
||||
fi
|
||||
|
||||
#
|
||||
@@ -99,8 +100,8 @@ parse_server_arguments() {
|
||||
--basedir=*) basedir=`echo "$arg" | sed -e 's/^[^=]*=//'`
|
||||
bindir="$basedir/bin"
|
||||
datadir="$basedir/data"
|
||||
sbindir="$basedir/bin"
|
||||
libexecdir="$basedir/bin"
|
||||
sbindir="$basedir/sbin"
|
||||
libexecdir="$basedir/libexec"
|
||||
;;
|
||||
--datadir=*) datadir=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
|
||||
--user=*) user=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
|
||||
@@ -240,7 +241,7 @@ case "$mode" in
|
||||
if test -x $libexecdir/mysqlmanager
|
||||
then
|
||||
manager=$libexecdir/mysqlmanager
|
||||
elif test -x $bindir/mysqlmanager
|
||||
elif test -x $sbindir/mysqlmanager
|
||||
then
|
||||
manager=$sbindir/mysqlmanager
|
||||
fi
|
||||
|
Reference in New Issue
Block a user