Commit b6717496 authored by unknown's avatar unknown

Merge mysql.com:/home/mydev/mysql-5.1

into  mysql.com:/home/mydev/mysql-5.1-bug8841

parents 78bec853 13adc06f
......@@ -1443,38 +1443,40 @@ int do_system(struct st_query *q)
/*
Print the content between echo and <delimiter> to result file.
If content is a variable, the variable value will be retrieved
Evaluate all variables in the string before printing, allow
for variable names to be escaped using \
SYNOPSIS
do_echo()
q called command
DESCRIPTION
Usage 1:
echo text
Print the text after echo until end of command to result file
Usage 2:
echo $<var_name>
Print the content of the variable <var_name> to result file
echo Some text $<var_name>
Print "Some text" plus the content of the variable <var_name> to
result file
echo Some text \$<var_name>
Print "Some text" plus $<var_name> to result file
*/
int do_echo(struct st_query *q)
int do_echo(struct st_query *command)
{
char *p= q->first_argument;
DYNAMIC_STRING *ds;
VAR v;
var_init(&v,0,0,0,0);
DYNAMIC_STRING *ds, ds_echo;
ds= &ds_res;
eval_expr(&v, p, 0); /* NULL terminated */
if (v.str_val_len)
dynstr_append_mem(ds, v.str_val, v.str_val_len);
init_dynamic_string(&ds_echo, "", 256, 256);
do_eval(&ds_echo, command->first_argument);
dynstr_append_mem(ds, ds_echo.str, ds_echo.length);
dynstr_append_mem(ds, "\n", 1);
var_free(&v);
q->last_argument= q->end;
dynstr_free(&ds_echo);
command->last_argument= command->end;
return 0;
}
......@@ -3733,7 +3735,7 @@ static void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
if (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
die("fetch didn't end with MYSQL_NO_DATA from statement: %d %s",
mysql_stmt_error(stmt), mysql_stmt_errno(stmt));
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
free_replace_column();
......@@ -4215,18 +4217,16 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
parameter markers.
*/
#ifdef BUG14013_FIXED
if (cursor_protocol_enabled)
{
/*
Use cursor when retrieving result
*/
if (cursor_protocol_enabled)
{
ulong type= CURSOR_TYPE_READ_ONLY;
if (mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type))
die("mysql_stmt_attr_set(STMT_ATTR_CURSOR_TYPE) failed': %d %s",
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
}
#endif
/*
Execute the query
......@@ -4238,6 +4238,13 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
goto end;
}
/*
When running in cursor_protocol get the warnings from execute here
and keep them in a separate string for later.
*/
if (cursor_protocol_enabled && !disable_warnings)
append_warnings(&ds_execute_warnings, mysql);
/*
We instruct that we want to update the "max_length" field in
mysql_stmt_store_result(), this is our only way to know how much
......@@ -4303,6 +4310,7 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
/* Append warnings to ds - if there are any */
if (append_warnings(&ds_execute_warnings, mysql) ||
ds_execute_warnings.length ||
ds_prepare_warnings.length ||
ds_warnings->length)
{
......
......@@ -2002,6 +2002,7 @@ mysql_stmt_init(MYSQL *mysql)
stmt->mysql= mysql;
stmt->read_row_func= stmt_read_row_no_result_set;
stmt->prefetch_rows= DEFAULT_PREFETCH_ROWS;
strmov(stmt->sqlstate, not_error_sqlstate);
/* The rest of statement members was bzeroed inside malloc */
DBUG_RETURN(stmt);
......@@ -4751,12 +4752,39 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
if (!stmt->field_count)
DBUG_RETURN(0);
if ((int) stmt->state < (int) MYSQL_STMT_EXECUTE_DONE ||
mysql->status != MYSQL_STATUS_GET_RESULT)
if ((int) stmt->state < (int) MYSQL_STMT_EXECUTE_DONE)
{
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
DBUG_RETURN(1);
}
if (mysql->status == MYSQL_STATUS_READY &&
stmt->server_status & SERVER_STATUS_CURSOR_EXISTS)
{
/*
Server side cursor exist, tell server to start sending the rows
*/
NET *net= &mysql->net;
char buff[4 /* statement id */ +
4 /* number of rows to fetch */];
/* Send row request to the server */
int4store(buff, stmt->stmt_id);
int4store(buff + 4, (int)~0); /* number of rows to fetch */
if (cli_advanced_command(mysql, COM_STMT_FETCH, buff, sizeof(buff),
NullS, 0, 1))
{
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
DBUG_RETURN(1);
}
}
else if (mysql->status != MYSQL_STATUS_GET_RESULT)
{
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
DBUG_RETURN(1);
}
if (result->data)
{
free_root(&result->alloc, MYF(MY_KEEP_PREALLOC));
......@@ -4797,6 +4825,10 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
DBUG_RETURN(1);
}
/* Assert that if there was a cursor, all rows have been fetched */
DBUG_ASSERT(mysql->status != MYSQL_STATUS_READY ||
(mysql->server_status & SERVER_STATUS_LAST_ROW_SENT));
if (stmt->update_max_length)
{
MYSQL_ROWS *cur= result->data;
......
create database if not exists events_test;
use events_test;
CREATE USER pauline@localhost;
CREATE DATABASE db_x;
GRANT EVENT ON db_x.* TO pauline@localhost;
USE db_x;
CREATE TABLE x_table(a int);
CREATE EVENT e_x1 ON SCHEDULE EVERY 1 SECOND DO DROP DATABASE db_x;
CREATE EVENT e_x2 ON SCHEDULE EVERY 1 SECOND DO DROP TABLE x_table;
SHOW DATABASES LIKE 'db_x';
Database (db_x)
db_x
SET GLOBAL event_scheduler=1;
SHOW DATABASES LIKE 'db_x';
Database (db_x)
db_x
SHOW TABLES FROM db_x;
Tables_in_db_x
x_table
SET GLOBAL event_scheduler=0;
DROP EVENT e_x1;
DROP EVENT e_x2;
DROP DATABASE db_x;
DROP USER pauline@localhost;
USE events_test;
SET GLOBAL event_scheduler=0;
drop event if exists event1;
Warnings:
Note 1305 Event event1 does not exist
......@@ -20,6 +44,14 @@ select db, name, body, status, interval_field, interval_value from mysql.event;
db name body status interval_field interval_value
events_test e_43 set @a = 4 ENABLED SECOND 1
drop event e_43;
"Let's check whether we can use non-qualified names"
create table non_qualif(a int);
create event non_qualif_ev on schedule every 10 minute do insert into non_qualif values (800219);
select * from non_qualif;
a
800219
drop event non_qualif_ev;
drop table non_qualif;
set global event_scheduler = 0;
create table t_event3 (a int, b float);
drop event if exists event3;
......@@ -331,8 +363,8 @@ create event закачка on schedule every 10 hour do select get_lock("test_l
show processlist;
Id User Host db Command Time State Info
# root localhost events_test Query # NULL show processlist
# event_scheduler NULL Connect # Sleeping NULL
# root events_test Connect # User lock select get_lock("test_lock2", 20)
# event_scheduler connecting host NULL Connect # Sleeping NULL
# root localhost events_test Connect # User lock select get_lock("test_lock2", 20)
"Release the mutex, the event worker should finish."
select release_lock("test_lock2");
release_lock("test_lock2")
......@@ -350,8 +382,7 @@ set global event_scheduler=0;
show processlist;
Id User Host db Command Time State Info
# root localhost events_test Query # NULL show processlist
# event_scheduler NULL Connect # Sleeping NULL
# root events_test Connect # User lock select get_lock("test_lock2_1", 20)
# event_scheduler connecting host NULL Connect # Sleeping NULL
"Release the lock so the child process should finish. Hence the scheduler also"
select release_lock("test_lock2_1");
release_lock("test_lock2_1")
......
CREATE DATABASE IF NOT EXISTS events_test;
CREATE DATABASE events_test2;
USE events_test2;
CREATE EVENT ev_drop1 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1;
CREATE EVENT ev_drop2 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1;
CREATE EVENT ev_drop3 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1;
USE events_test;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
COUNT(*)
3
DROP DATABASE events_test2;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
COUNT(*)
0
"Now testing stability - dropping db -> events while they are running"
CREATE DATABASE events_test2;
USE events_test2;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
COUNT(*)
1000
SET GLOBAL event_scheduler=1;
DROP DATABASE events_test2;
SET GLOBAL event_scheduler=0;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
COUNT(*)
0
CREATE DATABASE events_test3;
USE events_test3;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test3';
COUNT(*)
950
CREATE DATABASE events_test4;
USE events_test4;
CREATE DATABASE events_test2;
USE events_test2;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
COUNT(*)
1050
DROP DATABASE events_test2;
SET GLOBAL event_scheduler=0;
DROP DATABASE events_test3;
SET GLOBAL event_scheduler=1;
DROP DATABASE events_test4;
SET GLOBAL event_scheduler=1;
USE events_test;
DROP DATABASE events_test;
......@@ -201,8 +201,14 @@ source database
- world''s most
-- popular open
# source database
'$message'
"$message"
'# MySQL: The
- world''s most
-- popular open
# source database'
"# MySQL: The
- world''s most
-- popular open
# source database"
hej
hej
hej
......@@ -221,6 +227,15 @@ mysqltest: At line 1: Missing arguments to let
mysqltest: At line 1: Missing variable name in let
mysqltest: At line 1: Missing variable name in let
mysqltest: At line 1: Missing assignment operator in let
# Execute: --echo # <whatever> success: $success
# <whatever> success: 1
# Execute: echo # <whatever> success: $success ;
# <whatever> success: 1
# The next two variants work fine and expand the content of $success
# Execute: --echo $success
1
# Execute: echo $success ;
1
mysqltest: At line 1: Missing file name in source
mysqltest: At line 1: Could not open file ./non_existingFile
mysqltest: In included file "MYSQLTEST_VARDIR/tmp/recursive.sql": At line 1: Source directives are nesting too deep
......
......@@ -8,8 +8,6 @@ a b c
2 two two
alter table t1 drop index c;
select * from t1 where c = 'two';
ERROR HY000: Table definition has changed, please retry transaction
select * from t1 where c = 'two';
a b c
2 two two
drop table t1;
......
......@@ -30,14 +30,6 @@ drop table t1;
create table t1 (a int) engine=ndbcluster;
insert into t1 value (2);
select * from t1;
ERROR HY000: Table definition has changed, please retry transaction
show warnings;
Level Code Message
Error 1296 Got error 241 'Invalid schema object version' from NDB
Error 1412 Table definition has changed, please retry transaction
Error 1105 Unknown error
flush table t1;
select * from t1;
a
2
flush status;
......@@ -58,15 +50,9 @@ a
select * from t3;
a b c last_col
1 Hi! 89 Longtext column
show status like 'handler_discover%';
Variable_name Value
Handler_discover 1
show tables like 't4';
Tables_in_test (t4)
t4
show status like 'handler_discover%';
Variable_name Value
Handler_discover 2
show tables;
Tables_in_test
t1
......@@ -74,4 +60,3 @@ t2
t3
t4
drop table t1, t2, t3, t4;
drop table t1, t3, t4;
......@@ -300,3 +300,16 @@ select * from t1 where f1 = 10;
f1 f2
10 1
drop table t1;
set session storage_engine= 'memory';
create table t1 (f_int1 int(11) default null) engine = memory
partition by range (f_int1) subpartition by hash (f_int1)
(partition part1 values less than (1000)
(subpartition subpart11 engine = memory));
drop table t1;
set session storage_engine='myisam';
create table t1 (f_int1 integer, f_int2 integer, primary key (f_int1))
partition by hash(f_int1) partitions 2;
insert into t1 values (1,1),(2,2);
replace into t1 values (1,1),(2,2);
drop table t1;
End of 5.1 tests
......@@ -20,7 +20,6 @@ ndb_autodiscover2 : Needs to be fixed w.r.t binlog
ndb_binlog_basic : Results are not deterministic, Tomas will fix
ndb_binlog_ddl_multi : Bug#17038 [PATCH PENDING]
ndb_gis : garbled msgs from corrupt THD*
ndb_load : Bug#17233
partition_03ndb : Bug#16385
ps_7ndb : dbug assert in RBR mode when executing test suite
rpl_bit_npk : Bug#13418
......
create database if not exists events_test;
use events_test;
#
# START: BUG #17289 Events: missing privilege check for drop database
#
CREATE USER pauline@localhost;
CREATE DATABASE db_x;
GRANT EVENT ON db_x.* TO pauline@localhost;
USE db_x;
CREATE TABLE x_table(a int);
connect (priv_conn,localhost,pauline,,db_x);
CREATE EVENT e_x1 ON SCHEDULE EVERY 1 SECOND DO DROP DATABASE db_x;
CREATE EVENT e_x2 ON SCHEDULE EVERY 1 SECOND DO DROP TABLE x_table;
connection default;
SHOW DATABASES LIKE 'db_x';
SET GLOBAL event_scheduler=1;
--sleep 2
SHOW DATABASES LIKE 'db_x';
SHOW TABLES FROM db_x;
SET GLOBAL event_scheduler=0;
--sleep 1
connection priv_conn;
DROP EVENT e_x1;
DROP EVENT e_x2;
disconnect priv_conn;
connection default;
DROP DATABASE db_x;
DROP USER pauline@localhost;
USE events_test;
#
# END: BUG #17289 Events: missing privilege check for drop database
#
SET GLOBAL event_scheduler=0;
--sleep 1
drop event if exists event1;
create event event1 on schedule every 15 minute starts now() ends date_add(now(), interval 5 hour) DO begin end;
alter event event1 rename to event2 enable;
......@@ -23,6 +56,14 @@ alter event e_43 do alter event e_43 do set @a = 4;
select db, name, body, status, interval_field, interval_value from mysql.event;
drop event e_43;
--sleep 1
--echo "Let's check whether we can use non-qualified names"
create table non_qualif(a int);
create event non_qualif_ev on schedule every 10 minute do insert into non_qualif values (800219);
--sleep 2
select * from non_qualif;
drop event non_qualif_ev;
drop table non_qualif;
set global event_scheduler = 0;
create table t_event3 (a int, b float);
......@@ -241,7 +282,6 @@ drop event one_event;
--echo "Sleep a bit so the server closes the second connection"
--sleep 2
create event e_26 on schedule at '2017-01-01 00:00:00' disable do set @a = 5;
select db, name, body, definer, convert_tz(execute_at, 'UTC', 'SYSTEM'), on_completion from mysql.event;
drop event e_26;
......
CREATE DATABASE IF NOT EXISTS events_test;
#
# DROP DATABASE test start (bug #16406)
#
CREATE DATABASE events_test2;
USE events_test2;
CREATE EVENT ev_drop1 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1;
CREATE EVENT ev_drop2 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1;
CREATE EVENT ev_drop3 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1;
USE events_test;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
DROP DATABASE events_test2;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
--echo "Now testing stability - dropping db -> events while they are running"
CREATE DATABASE events_test2;
USE events_test2;
--disable_query_log
let $1= 1000;
while ($1)
{
eval CREATE EVENT ev_drop$1 ON SCHEDULE EVERY 1 SECOND DO SELECT $1;
dec $1;
}
--enable_query_log
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
SET GLOBAL event_scheduler=1;
--sleep 4
DROP DATABASE events_test2;
SET GLOBAL event_scheduler=0;
--sleep 2
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
CREATE DATABASE events_test3;
USE events_test3;
--disable_query_log
let $1= 950;
while ($1)
{
eval CREATE EVENT ev_drop$1 ON SCHEDULE EVERY 1 SECOND DO SELECT $1;
dec $1;
}
--enable_query_log
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test3';
--sleep 3
CREATE DATABASE events_test4;
USE events_test4;
--disable_query_log
let $1= 860;
while ($1)
{
eval CREATE EVENT ev_drop$1 ON SCHEDULE EVERY 1 SECOND DO SELECT $1;
dec $1;
}
--enable_query_log
CREATE DATABASE events_test2;
USE events_test2;
--disable_query_log
let $1= 1050;
while ($1)
{
eval CREATE EVENT ev_drop$1 ON SCHEDULE EVERY 1 SECOND DO SELECT $1;
dec $1;
}
--enable_query_log
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
--sleep 6
DROP DATABASE events_test2;
SET GLOBAL event_scheduler=0;
DROP DATABASE events_test3;
SET GLOBAL event_scheduler=1;
DROP DATABASE events_test4;
SET GLOBAL event_scheduler=1;
USE events_test;
#
# DROP DATABASE test end (bug #16406)
#
DROP DATABASE events_test;
......@@ -538,6 +538,19 @@ echo $novar1;
--error 1
--exec echo "let hi;" | $MYSQL_TEST 2>&1
# More advanced test for bug#17280
let $success= 1;
--echo # Execute: --echo # <whatever> success: \$success
--echo # <whatever> success: $success
--echo # Execute: echo # <whatever> success: \$success ;
echo # <whatever> success: $success ;
--echo # The next two variants work fine and expand the content of \$success
--echo # Execute: --echo \$success
--echo $success
--echo # Execute: echo \$success ;
echo $success ;
# ----------------------------------------------------------------------------
# Test to assign let from query
# let $<var_name>=`<query>`;
......
......@@ -17,8 +17,6 @@ select * from t1 where c = 'two';
connection server1;
alter table t1 drop index c;
connection server2;
-- error 1412
select * from t1 where c = 'two';
select * from t1 where c = 'two';
connection server1;
drop table t1;
......
......@@ -41,11 +41,12 @@ drop table t1;
create table t1 (a int) engine=ndbcluster;
insert into t1 value (2);
connection server1;
# Currently a retry is required remotely
--error 1412
select * from t1;
show warnings;
flush table t1;
## Currently a retry is required remotely
#--error 1412
#select * from t1;
#show warnings;
#flush table t1;
# Table definition change should be propagated automatically
select * from t1;
# Connect to server2 and use the tables from there
......@@ -65,13 +66,9 @@ create table t4 (pk int primary key, b int) engine=ndb;
connection server1;
select * from t1;
select * from t3;
show status like 'handler_discover%';
show tables like 't4';
show status like 'handler_discover%';
show tables;
drop table t1, t2, t3, t4;
connection server2;
drop table t1, t3, t4;
# End of 4.1 tests
......@@ -380,3 +380,25 @@ partition partf values less than (10000));
insert into t1 values(10,1);
select * from t1 where f1 = 10;
drop table t1;
#
# Bug #16775: Wrong engine type stored for subpartition
#
set session storage_engine= 'memory';
create table t1 (f_int1 int(11) default null) engine = memory
partition by range (f_int1) subpartition by hash (f_int1)
(partition part1 values less than (1000)
(subpartition subpart11 engine = memory));
drop table t1;
set session storage_engine='myisam';
#
# Bug #16782: Crash using REPLACE on table with primary key
#
create table t1 (f_int1 integer, f_int2 integer, primary key (f_int1))
partition by hash(f_int1) partitions 2;
insert into t1 values (1,1),(2,2);
replace into t1 values (1,1),(2,2);
drop table t1;
--echo End of 5.1 tests
This diff is collapsed.
......@@ -79,6 +79,8 @@ class event_timed
{
event_timed(const event_timed &); /* Prevent use of these */
void operator=(event_timed &);
my_bool in_spawned_thread;
ulong locked_by_thread_id;
my_bool running;
pthread_mutex_t LOCK_running;
......@@ -117,12 +119,13 @@ public:
bool free_sphead_on_delete;
uint flags;//all kind of purposes
event_timed():running(0), status_changed(false), last_executed_changed(false),
expression(0), created(0), modified(0),
on_completion(MYSQL_EVENT_ON_COMPLETION_DROP),
event_timed():in_spawned_thread(0),locked_by_thread_id(0),
running(0), status_changed(false),
last_executed_changed(false), expression(0), created(0),
modified(0), on_completion(MYSQL_EVENT_ON_COMPLETION_DROP),
status(MYSQL_EVENT_ENABLED), sphead(0), sql_mode(0),
body_begin(0), dropped(false), free_sphead_on_delete(true),
flags(0)
body_begin(0), dropped(false),
free_sphead_on_delete(true), flags(0)
{
pthread_mutex_init(&this->LOCK_running, MY_MUTEX_INIT_FAST);
......@@ -200,11 +203,55 @@ public:
return ret;
}
void free_sp()
/*
Checks whether the object is being used in a spawned thread.
This method is for very basic checking. Use ::can_spawn_now_n_lock()
for most of the cases.
*/
my_bool
can_spawn_now()
{
my_bool ret;
VOID(pthread_mutex_lock(&this->LOCK_running));
ret= !in_spawned_thread;
VOID(pthread_mutex_unlock(&this->LOCK_running));
return ret;
}
/*
Checks whether this thread can lock the object for modification ->
preventing being spawned for execution, and locks if possible.
use ::can_spawn_now() only for basic checking because a race
condition may occur between the check and eventual modification (deletion)
of the object.
*/
my_bool
can_spawn_now_n_lock(THD *thd);
int
spawn_unlock(THD *thd);
int
spawn_now(void * (*thread_func)(void*));
void
spawn_thread_finish(THD *thd);
void
free_sp()
{
delete sphead;
sphead= 0;
}
protected:
bool
change_security_context(THD *thd, Security_context *s_ctx,
Security_context **backup);
void
restore_security_context(THD *thd, Security_context *backup);
};
......@@ -233,6 +280,10 @@ event_reconstruct_interval_expression(String *buf,
interval_type interval,
longlong expression);
int
evex_drop_db_events(THD *thd, char *db);
int
init_events();
......
This diff is collapsed.
......@@ -19,6 +19,10 @@
#include "mysql_priv.h"
#define EVENT_EXEC_STARTED 0
#define EVENT_EXEC_ALREADY_EXEC 1
#define EVENT_EXEC_CANT_FORK 2
#define EVEX_USE_QUEUE
#define UNLOCK_MUTEX_AND_BAIL_OUT(__mutex, __label) \
......@@ -32,9 +36,9 @@ int
my_time_compare(TIME *a, TIME *b);
int
evex_db_find_event_aux(THD *thd, const LEX_STRING dbname,
const LEX_STRING rname,
const LEX_STRING definer,
evex_db_find_event_by_name(THD *thd, const LEX_STRING dbname,
const LEX_STRING ev_name,
const LEX_STRING user_name,
TABLE *table);
int
......
......@@ -412,21 +412,30 @@ event_timed::init_definer(THD *thd)
{
DBUG_ENTER("event_timed::init_definer");
DBUG_PRINT("info",("init definer_user thd->mem_root=0x%lx "
"thd->sec_ctx->priv_user=0x%lx", thd->mem_root,
thd->security_ctx->priv_user));
definer_user.str= strdup_root(thd->mem_root, thd->security_ctx->priv_user);
definer_user.length= strlen(thd->security_ctx->priv_user);
DBUG_PRINT("info",("init definer_host thd->s_c->priv_host=0x%lx",
thd->security_ctx->priv_host));
definer_host.str= strdup_root(thd->mem_root, thd->security_ctx->priv_host);
definer_host.length= strlen(thd->security_ctx->priv_host);
DBUG_PRINT("info",("init definer as whole"));
definer.length= definer_user.length + definer_host.length + 1;
definer.str= alloc_root(thd->mem_root, definer.length + 1);
DBUG_PRINT("info",("copy the user"));
memcpy(definer.str, definer_user.str, definer_user.length);
definer.str[definer_user.length]= '@';
DBUG_PRINT("info",("copy the host"));
memcpy(definer.str + definer_user.length + 1, definer_host.str,
definer_host.length);
definer.str[definer.length]= '\0';
DBUG_PRINT("info",("definer initted"));
DBUG_RETURN(0);
}
......@@ -908,7 +917,7 @@ event_timed::drop(THD *thd)
Saves status and last_executed_at to the disk if changed.
SYNOPSIS
event_timed::drop()
event_timed::update_fields()
thd - thread context
RETURN VALUE
......@@ -945,7 +954,7 @@ event_timed::update_fields(THD *thd)
}
if ((ret= evex_db_find_event_aux(thd, dbname, name, definer, table)))
if ((ret= evex_db_find_event_by_name(thd, dbname, name, definer, table)))
goto done;
store_record(table,record[1]);
......@@ -1061,6 +1070,7 @@ event_timed::get_create_event(THD *thd, String *buf)
RETURNS
0 success
-99 No rights on this.dbname.str
-100 event in execution (parallel execution is impossible)
others retcodes of sp_head::execute_procedure()
*/
......@@ -1068,10 +1078,14 @@ event_timed::get_create_event(THD *thd, String *buf)
int
event_timed::execute(THD *thd, MEM_ROOT *mem_root)
{
List<Item> empty_item_list;
Security_context *save_ctx;
/* this one is local and not needed after exec */
Security_context security_ctx;
int ret= 0;
DBUG_ENTER("event_timed::execute");
DBUG_PRINT("info", (" EVEX EXECUTING event %s.%s [EXPR:%d]",
dbname.str, name.str, (int) expression));
VOID(pthread_mutex_lock(&this->LOCK_running));
if (running)
......@@ -1082,30 +1096,110 @@ event_timed::execute(THD *thd, MEM_ROOT *mem_root)
running= true;
VOID(pthread_mutex_unlock(&this->LOCK_running));
// TODO Andrey : make this as member variable and delete in destructor
empty_item_list.empty();
DBUG_PRINT("info", ("master_access=%d db_access=%d",
thd->security_ctx->master_access, thd->security_ctx->db_access));
change_security_context(thd, &security_ctx, &save_ctx);
DBUG_PRINT("info", ("master_access=%d db_access=%d",
thd->security_ctx->master_access, thd->security_ctx->db_access));
if (!sphead && (ret= compile(thd, mem_root)))
goto done;
/* Now we are sure we have valid this->sphead so we can copy the context */
sphead->m_security_ctx= security_ctx;
thd->db= dbname.str;
thd->db_length= dbname.length;
if (!check_access(thd, EVENT_ACL,dbname.str, 0, 0, 0,is_schema_db(dbname.str)))
{
List<Item> empty_item_list;
empty_item_list.empty();
ret= sphead->execute_procedure(thd, &empty_item_list);
}
else
{
DBUG_PRINT("error", ("%s@%s has no rights on %s", definer_user.str,
definer_host.str, dbname.str));
ret= -99;
}
restore_security_context(thd, save_ctx);
DBUG_PRINT("info", ("master_access=%d db_access=%d",
thd->security_ctx->master_access, thd->security_ctx->db_access));
thd->db= 0;
VOID(pthread_mutex_lock(&this->LOCK_running));
running= false;
VOID(pthread_mutex_unlock(&this->LOCK_running));
done:
// Don't cache sphead if allocated on another mem_root
/*
1. Don't cache sphead if allocated on another mem_root
2. Don't call security_ctx.destroy() because this will free our dbname.str
name.str and definer.str
*/
if (mem_root && sphead)
{
delete sphead;
sphead= 0;
}
DBUG_PRINT("info", (" EVEX EXECUTED event %s.%s [EXPR:%d]. RetCode=%d",
dbname.str, name.str, (int) expression, ret));
DBUG_RETURN(ret);
}
/*
Switches the security context
Synopsis
event_timed::change_security_context()
thd - thread
backup - where to store the old context
RETURN
0 - OK
1 - Error (generates error too)
*/
bool
event_timed::change_security_context(THD *thd, Security_context *s_ctx,
Security_context **backup)
{
DBUG_ENTER("event_timed::change_security_context");
DBUG_PRINT("info",("%s@%s@%s",definer_user.str,definer_host.str, dbname.str));
#ifndef NO_EMBEDDED_ACCESS_CHECKS
s_ctx->init();
*backup= 0;
if (acl_getroot_no_password(s_ctx, definer_user.str, definer_host.str,
definer_host.str, dbname.str))
{
my_error(ER_NO_SUCH_USER, MYF(0), definer_user.str, definer_host.str);
DBUG_RETURN(TRUE);
}
*backup= thd->security_ctx;
thd->security_ctx= s_ctx;
#endif
DBUG_RETURN(FALSE);
}
/*
Restores the security context
Synopsis
event_timed::restore_security_context()
thd - thread
backup - switch to this context
*/
void
event_timed::restore_security_context(THD *thd, Security_context *backup)
{
DBUG_ENTER("event_timed::change_security_context");
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (backup)
thd->security_ctx= backup;
#endif
DBUG_VOID_RETURN;
}
/*
Compiles an event before it's execution. Compiles the anonymous
sp_head object held by the event
......@@ -1128,6 +1222,7 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
MEM_ROOT *tmp_mem_root= 0;
LEX *old_lex= thd->lex, lex;
char *old_db;
int old_db_length;
event_timed *ett;
sp_name *spn;
char *old_query;
......@@ -1161,7 +1256,9 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
old_query_len= thd->query_length;
old_query= thd->query;
old_db= thd->db;
old_db_length= thd->db_length;
thd->db= dbname.str;
thd->db_length= dbname.length;
get_create_event(thd, &show_create);
......@@ -1227,3 +1324,135 @@ done:
DBUG_RETURN(ret);
}
/*
Checks whether this thread can lock the object for modification ->
preventing being spawned for execution, and locks if possible.
use ::can_spawn_now() only for basic checking because a race
condition may occur between the check and eventual modification (deletion)
of the object.
Returns
true - locked
false - cannot lock
*/
my_bool
event_timed::can_spawn_now_n_lock(THD *thd)
{
my_bool ret= FALSE;
VOID(pthread_mutex_lock(&this->LOCK_running));
if (!in_spawned_thread)
{
in_spawned_thread= TRUE;
ret= TRUE;
locked_by_thread_id= thd->thread_id;
}
VOID(pthread_mutex_unlock(&this->LOCK_running));
return ret;
}
extern pthread_attr_t connection_attrib;
/*
Checks whether is possible and forks a thread. Passes self as argument.
Returns
EVENT_EXEC_STARTED - OK
EVENT_EXEC_ALREADY_EXEC - Thread not forked, already working
EVENT_EXEC_CANT_FORK - Unable to spawn thread (error)
*/
int
event_timed::spawn_now(void * (*thread_func)(void*))
{
int ret= EVENT_EXEC_STARTED;
static uint exec_num= 0;
DBUG_ENTER("event_timed::spawn_now");
DBUG_PRINT("info", ("[%s.%s]", dbname.str, name.str));
VOID(pthread_mutex_lock(&this->LOCK_running));
if (!in_spawned_thread)
{
pthread_t th;
in_spawned_thread= true;
if (pthread_create(&th, &connection_attrib, thread_func, (void*)this))
{
DBUG_PRINT("info", ("problem while spawning thread"));
ret= EVENT_EXEC_CANT_FORK;
in_spawned_thread= false;
}
#ifndef DBUG_OFF
else
{
sql_print_information("SCHEDULER: Started thread %d", ++exec_num);
DBUG_PRINT("info", ("thread spawned"));
}
#endif
}
else
{
DBUG_PRINT("info", ("already in spawned thread. skipping"));
ret= EVENT_EXEC_ALREADY_EXEC;
}
VOID(pthread_mutex_unlock(&this->LOCK_running));
DBUG_RETURN(ret);
}
void
event_timed::spawn_thread_finish(THD *thd)
{
DBUG_ENTER("event_timed::spawn_thread_finish");
VOID(pthread_mutex_lock(&this->LOCK_running));
in_spawned_thread= false;
if ((flags & EVENT_EXEC_NO_MORE) || status == MYSQL_EVENT_DISABLED)
{
DBUG_PRINT("info", ("%s exec no more. to drop=%d", name.str, dropped));
if (dropped)
drop(thd);
VOID(pthread_mutex_unlock(&this->LOCK_running));
delete this;
DBUG_VOID_RETURN;
}
VOID(pthread_mutex_unlock(&this->LOCK_running));
DBUG_VOID_RETURN;
}
/*
Unlocks the object after it has been locked with ::can_spawn_now_n_lock()
Returns
0 - ok
1 - not locked by this thread
*/
int
event_timed::spawn_unlock(THD *thd)
{
int ret= 0;
VOID(pthread_mutex_lock(&this->LOCK_running));
if (!in_spawned_thread)
{
if (locked_by_thread_id == thd->thread_id)
{
in_spawned_thread= FALSE;
locked_by_thread_id= 0;
}
else
{
sql_print_error("A thread tries to unlock when he hasn't locked. "
"thread_id=%ld locked by %ld",
thd->thread_id, locked_by_thread_id);
DBUG_ASSERT(0);
ret= 1;
}
}
VOID(pthread_mutex_unlock(&this->LOCK_running));
return ret;
}
This diff is collapsed.
......@@ -237,10 +237,33 @@ void ndbcluster_binlog_init_share(NDB_SHARE *share, TABLE *_table)
{
THD *thd= current_thd;
MEM_ROOT *mem_root= &share->mem_root;
int do_event_op= ndb_binlog_running;
share->op= 0;
share->table= 0;
if (!ndb_binlog_running)
if (!schema_share &&
strcmp(share->db, NDB_REP_DB) == 0 &&
strcmp(share->table_name, NDB_SCHEMA_TABLE) == 0)
do_event_op= 1;
{
int i, no_nodes= g_ndb_cluster_connection->no_db_nodes();
share->subscriber_bitmap= (MY_BITMAP*)
alloc_root(mem_root, no_nodes * sizeof(MY_BITMAP));
for (i= 0; i < no_nodes; i++)
{
bitmap_init(&share->subscriber_bitmap[i],
(Uint32*)alloc_root(mem_root, max_ndb_nodes/8),
max_ndb_nodes, false);
bitmap_clear_all(&share->subscriber_bitmap[i]);
}
bitmap_init(&share->slock_bitmap, share->slock,
sizeof(share->slock)*8, false);
bitmap_clear_all(&share->slock_bitmap);
}
if (!do_event_op)
{
if (_table)
{
......@@ -315,21 +338,6 @@ void ndbcluster_binlog_init_share(NDB_SHARE *share, TABLE *_table)
share->ndb_value[1]= (NdbValue*)
alloc_root(mem_root, sizeof(NdbValue) * table->s->fields
+1 /*extra for hidden key*/);
{
int i, no_nodes= g_ndb_cluster_connection->no_db_nodes();
share->subscriber_bitmap= (MY_BITMAP*)
alloc_root(mem_root, no_nodes * sizeof(MY_BITMAP));
for (i= 0; i < no_nodes; i++)
{
bitmap_init(&share->subscriber_bitmap[i],
(Uint32*)alloc_root(mem_root, max_ndb_nodes/8),
max_ndb_nodes, false);
bitmap_clear_all(&share->subscriber_bitmap[i]);
}
bitmap_init(&share->slock_bitmap, share->slock,
sizeof(share->slock)*8, false);
bitmap_clear_all(&share->slock_bitmap);
}
if (table->s->primary_key == MAX_KEY)
share->flags|= NSF_HIDDEN_PK;
if (table->s->blob_fields != 0)
......@@ -648,11 +656,8 @@ static int ndbcluster_create_apply_status_table(THD *thd)
if so, remove it since there is none in Ndb
*/
{
strxnmov(buf, sizeof(buf),
mysql_data_home,
"/" NDB_REP_DB "/" NDB_APPLY_TABLE,
reg_ext, NullS);
unpack_filename(buf,buf);
build_table_filename(buf, sizeof(buf),
NDB_REP_DB, NDB_APPLY_TABLE, reg_ext);
my_delete(buf, MYF(0));
}
......@@ -700,11 +705,8 @@ static int ndbcluster_create_schema_table(THD *thd)
if so, remove it since there is none in Ndb
*/
{
strxnmov(buf, sizeof(buf),
mysql_data_home,
"/" NDB_REP_DB "/" NDB_SCHEMA_TABLE,
reg_ext, NullS);
unpack_filename(buf,buf);
build_table_filename(buf, sizeof(buf),
NDB_REP_DB, NDB_SCHEMA_TABLE, reg_ext);
my_delete(buf, MYF(0));
}
......@@ -929,8 +931,7 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share,
if (get_a_share)
{
char key[FN_REFLEN];
(void)strxnmov(key, FN_REFLEN, share_prefix, db,
"/", table_name, NullS);
build_table_filename(key, sizeof(key), db, table_name, "");
share= get_share(key, 0, false, false);
}
......@@ -1358,6 +1359,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
switch (ev_type)
{
case NDBEVENT::TE_UPDATE:
/* fall through */
case NDBEVENT::TE_INSERT:
{
Cluster_replication_schema *schema= (Cluster_replication_schema *)
......@@ -1375,21 +1377,20 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
{
case SOT_DROP_TABLE:
/* binlog dropping table after any table operations */
if (ndb_binlog_running)
post_epoch_log_list->push_back(schema, mem_root);
log_query= 0;
break;
case SOT_RENAME_TABLE:
/* fall through */
case SOT_ALTER_TABLE:
/* fall through */
if (!ndb_binlog_running)
if (ndb_binlog_running)
{
log_query= 1;
break; /* discovery will be handled by binlog */
}
/* fall through */
case SOT_CREATE_TABLE:
/* fall through */
pthread_mutex_lock(&LOCK_open);
if (ndb_create_table_from_engine(thd, schema->db, schema->name))
{
......@@ -1407,6 +1408,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
TRUE, /* print error */
TRUE); /* don't binlog the query */
/* binlog dropping database after any table operations */
if (ndb_binlog_running)
post_epoch_log_list->push_back(schema, mem_root);
log_query= 0;
break;
......@@ -1422,8 +1424,8 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
case SOT_CLEAR_SLOCK:
{
char key[FN_REFLEN];
(void)strxnmov(key, FN_REFLEN, share_prefix, schema->db,
"/", schema->name, NullS);
build_table_filename(key, sizeof(key),
schema->db, schema->name, "");
NDB_SHARE *share= get_share(key, 0, false, false);
if (share)
{
......@@ -1463,7 +1465,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
}
}
if (log_query)
if (log_query && ndb_binlog_running)
{
char *thd_db_save= thd->db;
thd->db= schema->db;
......@@ -1752,6 +1754,7 @@ int ndbcluster_create_binlog_setup(Ndb *ndb, const char *key,
const char *table_name,
my_bool share_may_exist)
{
int do_event_op= ndb_binlog_running;
DBUG_ENTER("ndbcluster_create_binlog_setup");
DBUG_PRINT("enter",("key: %s key_len: %d %s.%s share_may_exist: %d",
key, key_len, db, table_name, share_may_exist));
......@@ -1792,7 +1795,12 @@ int ndbcluster_create_binlog_setup(Ndb *ndb, const char *key,
"allocating table share for %s failed", key);
}
if (!ndb_binlog_running)
if (!schema_share &&
strcmp(share->db, NDB_REP_DB) == 0 &&
strcmp(share->table_name, NDB_SCHEMA_TABLE) == 0)
do_event_op= 1;
if (!do_event_op)
{
share->flags|= NSF_NO_BINLOG;
pthread_mutex_unlock(&ndbcluster_mutex);
......
......@@ -360,7 +360,7 @@ int ha_partition::ha_initialise()
other parameters are calculated on demand.
HA_FILE_BASED is always set for partition handler since we use a
special file for handling names of partitions, engine types.
HA_CAN_GEOMETRY, HA_CAN_FULLTEXT, HA_CAN_SQL_HANDLER,
HA_CAN_GEOMETRY, HA_CAN_FULLTEXT, HA_CAN_SQL_HANDLER, HA_DUPP_POS,
HA_CAN_INSERT_DELAYED is disabled until further investigated.
*/
m_table_flags= m_file[0]->table_flags();
......@@ -383,8 +383,8 @@ int ha_partition::ha_initialise()
m_pkey_is_clustered= FALSE;
m_table_flags&= file->table_flags();
} while (*(++file_array));
m_table_flags&= ~(HA_CAN_GEOMETRY & HA_CAN_FULLTEXT &
HA_CAN_SQL_HANDLER & HA_CAN_INSERT_DELAYED);
m_table_flags&= ~(HA_CAN_GEOMETRY | HA_CAN_FULLTEXT | HA_DUPP_POS |
HA_CAN_SQL_HANDLER | HA_CAN_INSERT_DELAYED);
m_table_flags|= HA_FILE_BASED | HA_REC_NOT_IN_SEQ;
DBUG_RETURN(0);
}
......@@ -1937,7 +1937,8 @@ bool ha_partition::create_handler_file(const char *name)
name_buffer_ptr+= name_add(name_buffer_ptr,
part_name,
subpart_name);
*engine_array= (uchar) ha_legacy_type(part_elem->engine_type);
*engine_array= (uchar) ha_legacy_type(subpart_elem->engine_type);
DBUG_PRINT("info", ("engine: %u", *engine_array));
engine_array++;
}
}
......@@ -1954,7 +1955,7 @@ bool ha_partition::create_handler_file(const char *name)
Create and write and close file
to be used at open, delete_table and rename_table
*/
fn_format(file_name, name, "", ".par", MY_APPEND_EXT);
fn_format(file_name, name, "", ha_par_ext, MY_APPEND_EXT);
if ((file= my_create(file_name, CREATE_MODE, O_RDWR | O_TRUNC,
MYF(MY_WME))) >= 0)
{
......@@ -4683,6 +4684,7 @@ int ha_partition::extra(enum ha_extra_function operation)
case HA_EXTRA_PREPARE_FOR_UPDATE:
case HA_EXTRA_PREPARE_FOR_DELETE:
case HA_EXTRA_FORCE_REOPEN:
case HA_EXTRA_FLUSH_CACHE:
{
if (m_myisam)
DBUG_RETURN(loop_extra(operation));
......
......@@ -3488,7 +3488,7 @@ byte *sys_var_thd_dbug::value_ptr(THD *thd, enum_var_type type, LEX_STRING *b)
DBUG_EXPLAIN_INITIAL(buf, sizeof(buf));
else
DBUG_EXPLAIN(buf, sizeof(buf));
(byte*) thd->strdup(buf);
return (byte*) thd->strdup(buf);
}
/****************************************************************************
......
......@@ -20,6 +20,7 @@
#include "mysql_priv.h"
#include <mysys_err.h>
#include "sp.h"
#include "event.h"
#include <my_dir.h>
#include <m_ctype.h>
#ifdef __WIN__
......@@ -870,6 +871,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
exit:
(void)sp_drop_db_routines(thd, db); /* QQ Ignore errors for now */
(void)evex_drop_db_events(thd, db); /* QQ Ignore errors for now */
start_waiting_global_read_lock(thd);
/*
If this database was the client's selected database, we silently change the
......
......@@ -211,8 +211,13 @@ void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
TRUE Error sending data to client
*/
static const char *warning_level_names[]= {"Note", "Warning", "Error", "?"};
static int warning_level_length[]= { 4, 7, 5, 1 };
LEX_STRING warning_level_names[]=
{
{(char*) STRING_WITH_LEN("Note")},
{(char*) STRING_WITH_LEN("Warning")},
{(char*) STRING_WITH_LEN("Error")},
{(char*) STRING_WITH_LEN("?")}
};
bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
{
......@@ -246,8 +251,8 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
if (idx > unit->select_limit_cnt)
break;
protocol->prepare_for_resend();
protocol->store(warning_level_names[err->level],
warning_level_length[err->level], system_charset_info);
protocol->store(warning_level_names[err->level].str,
warning_level_names[err->level].length, system_charset_info);
protocol->store((uint32) err->code);
protocol->store(err->msg, strlen(err->msg), system_charset_info);
if (protocol->write())
......
......@@ -191,10 +191,8 @@ public:
int flush() const;
private:
STATIC_CONST( MAX_FILE_NAME_SIZE = 128 );
FILE* m_file;
char m_fileName[MAX_FILE_NAME_SIZE];
char m_fileName[PATH_MAX];
const char* m_fileMode;
/* Prohibit */
File_class (const File_class& aCopy);
......
......@@ -64,11 +64,11 @@ NdbConfig_NdbCfgName(int with_ndb_home){
int len= 0;
if (with_ndb_home) {
buf= NdbConfig_AllocHomePath(128);
buf= NdbConfig_AllocHomePath(PATH_MAX);
len= strlen(buf);
} else
buf= NdbMem_Allocate(128);
basestring_snprintf(buf+len, 128, "Ndb.cfg");
buf= NdbMem_Allocate(PATH_MAX);
basestring_snprintf(buf+len, PATH_MAX, "Ndb.cfg");
return buf;
}
......@@ -90,56 +90,56 @@ char *get_prefix_buf(int len, int node_id)
char*
NdbConfig_ErrorFileName(int node_id){
char *buf= get_prefix_buf(128, node_id);
char *buf= get_prefix_buf(PATH_MAX, node_id);
int len= strlen(buf);
basestring_snprintf(buf+len, 128, "_error.log");
basestring_snprintf(buf+len, PATH_MAX, "_error.log");
return buf;
}
char*
NdbConfig_ClusterLogFileName(int node_id){
char *buf= get_prefix_buf(128, node_id);
char *buf= get_prefix_buf(PATH_MAX, node_id);
int len= strlen(buf);
basestring_snprintf(buf+len, 128, "_cluster.log");
basestring_snprintf(buf+len, PATH_MAX, "_cluster.log");
return buf;
}
char*
NdbConfig_SignalLogFileName(int node_id){
char *buf= get_prefix_buf(128, node_id);
char *buf= get_prefix_buf(PATH_MAX, node_id);
int len= strlen(buf);
basestring_snprintf(buf+len, 128, "_signal.log");
basestring_snprintf(buf+len, PATH_MAX, "_signal.log");
return buf;
}
char*
NdbConfig_TraceFileName(int node_id, int file_no){
char *buf= get_prefix_buf(128, node_id);
char *buf= get_prefix_buf(PATH_MAX, node_id);
int len= strlen(buf);
basestring_snprintf(buf+len, 128, "_trace.log.%u", file_no);
basestring_snprintf(buf+len, PATH_MAX, "_trace.log.%u", file_no);
return buf;
}
char*
NdbConfig_NextTraceFileName(int node_id){
char *buf= get_prefix_buf(128, node_id);
char *buf= get_prefix_buf(PATH_MAX, node_id);
int len= strlen(buf);
basestring_snprintf(buf+len, 128, "_trace.log.next");
basestring_snprintf(buf+len, PATH_MAX, "_trace.log.next");
return buf;
}
char*
NdbConfig_PidFileName(int node_id){
char *buf= get_prefix_buf(128, node_id);
char *buf= get_prefix_buf(PATH_MAX, node_id);
int len= strlen(buf);
basestring_snprintf(buf+len, 128, ".pid");
basestring_snprintf(buf+len, PATH_MAX, ".pid");
return buf;
}
char*
NdbConfig_StdoutFileName(int node_id){
char *buf= get_prefix_buf(128, node_id);
char *buf= get_prefix_buf(PATH_MAX, node_id);
int len= strlen(buf);
basestring_snprintf(buf+len, 128, "_out.log");
basestring_snprintf(buf+len, PATH_MAX, "_out.log");
return buf;
}
......@@ -67,7 +67,7 @@ File_class::File_class(const char* aFileName, const char* mode) :
m_file(NULL),
m_fileMode(mode)
{
BaseString::snprintf(m_fileName, MAX_FILE_NAME_SIZE, aFileName);
BaseString::snprintf(m_fileName, PATH_MAX, aFileName);
}
bool
......@@ -83,7 +83,7 @@ File_class::open(const char* aFileName, const char* mode)
/**
* Only copy if it's not the same string
*/
BaseString::snprintf(m_fileName, MAX_FILE_NAME_SIZE, aFileName);
BaseString::snprintf(m_fileName, PATH_MAX, aFileName);
}
m_fileMode = mode;
bool rc = true;
......
......@@ -1049,7 +1049,10 @@ void stmt_fetch_close(Stmt_fetch *fetch)
reading from the rest.
*/
my_bool fetch_n(const char **query_list, unsigned query_count)
enum fetch_type { USE_ROW_BY_ROW_FETCH= 0, USE_STORE_RESULT= 1 };
my_bool fetch_n(const char **query_list, unsigned query_count,
enum fetch_type fetch_type)
{
unsigned open_statements= query_count;
int rc, error_count= 0;
......@@ -1065,6 +1068,15 @@ my_bool fetch_n(const char **query_list, unsigned query_count)
query_list[fetch - fetch_array]);
}
if (fetch_type == USE_STORE_RESULT)
{
for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch)
{
rc= mysql_stmt_store_result(fetch->handle);
check_execute(fetch->handle, rc);
}
}
while (open_statements)
{
for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch)
......@@ -11867,7 +11879,8 @@ static void test_basic_cursors()
fill_tables(basic_tables, sizeof(basic_tables)/sizeof(*basic_tables));
fetch_n(queries, sizeof(queries)/sizeof(*queries));
fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
DBUG_VOID_RETURN;
}
......@@ -11880,7 +11893,8 @@ static void test_cursors_with_union()
"SELECT t1.id FROM t1 WHERE t1.id < 5"
};
myheader("test_cursors_with_union");
fetch_n(queries, sizeof(queries)/sizeof(*queries));
fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
}
/*
......@@ -14729,6 +14743,21 @@ static void test_bug12744()
client_connect(0);
}
/* Bug #16143: mysql_stmt_sqlstate returns an empty string instead of '00000' */
static void test_bug16143()
{
MYSQL_STMT *stmt;
myheader("test_bug16143");
stmt= mysql_stmt_init(mysql);
/* Check mysql_stmt_sqlstate return "no error" */
DIE_UNLESS(strcmp(mysql_stmt_sqlstate(stmt), "00000") == 0);
mysql_stmt_close(stmt);
}
/* Bug #16144: mysql_stmt_attr_get type error */
static void test_bug16144()
......@@ -15072,6 +15101,7 @@ static struct my_tests_st my_tests[]= {
{ "test_opt_reconnect", test_opt_reconnect },
{ "test_bug15510", test_bug15510},
{ "test_bug12744", test_bug12744 },
{ "test_bug16143", test_bug16143 },
{ "test_bug16144", test_bug16144 },
{ "test_bug15613", test_bug15613 },
{ 0, 0 }
......
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