mirror of
https://github.com/MariaDB/server.git
synced 2025-08-05 13:16:09 +03:00
Merge kpdesk.mysql.com:/home/thek/Development/cpp/mysql-5.1
into kpdesk.mysql.com:/home/thek/Development/cpp/mysql-5.1-merge
This commit is contained in:
@@ -1218,6 +1218,12 @@ DROP USER mysqltest_1@localhost;
|
|||||||
DROP DATABASE db27878;
|
DROP DATABASE db27878;
|
||||||
use test;
|
use test;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Bug#33275 Server crash when creating temporary table mysql.user
|
||||||
|
#
|
||||||
|
CREATE TEMPORARY TABLE mysql.user (id INT);
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
DROP TABLE mysql.user;
|
||||||
drop table if exists test;
|
drop table if exists test;
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1051 Unknown table 'test'
|
Note 1051 Unknown table 'test'
|
||||||
|
@@ -249,4 +249,25 @@ set global slow_query_log_file= NULL;
|
|||||||
ERROR 42000: Variable 'slow_query_log_file' can't be set to the value of 'NULL'
|
ERROR 42000: Variable 'slow_query_log_file' can't be set to the value of 'NULL'
|
||||||
set global general_log_file= @old_general_log_file;
|
set global general_log_file= @old_general_log_file;
|
||||||
set global slow_query_log_file= @old_slow_query_log_file;
|
set global slow_query_log_file= @old_slow_query_log_file;
|
||||||
|
|
||||||
|
# --
|
||||||
|
# -- Bug#32748: Inconsistent handling of assignments to
|
||||||
|
# -- general_log_file/slow_query_log_file.
|
||||||
|
# --
|
||||||
|
|
||||||
|
SET @general_log_file_saved = @@global.general_log_file;
|
||||||
|
SET @slow_query_log_file_saved = @@global.slow_query_log_file;
|
||||||
|
|
||||||
|
SET GLOBAL general_log_file = 'bug32748.query.log';
|
||||||
|
SET GLOBAL slow_query_log_file = 'bug32748.slow.log';
|
||||||
|
|
||||||
|
SHOW VARIABLES LIKE '%log_file';
|
||||||
|
Variable_name Value
|
||||||
|
general_log_file bug32748.query.log
|
||||||
|
slow_query_log_file bug32748.slow.log
|
||||||
|
|
||||||
|
SET GLOBAL general_log_file = @general_log_file_saved;
|
||||||
|
SET GLOBAL slow_query_log_file = @slow_query_log_file_saved;
|
||||||
|
|
||||||
|
# -- End of Bug#32748.
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1014,3 +1014,13 @@ Variable_name='table_lock_wait_timeout';
|
|||||||
Variable_name Value
|
Variable_name Value
|
||||||
table_definition_cache #
|
table_definition_cache #
|
||||||
table_lock_wait_timeout #
|
table_lock_wait_timeout #
|
||||||
|
|
||||||
|
# --
|
||||||
|
# -- Bug#34820: log_output can be set to illegal value.
|
||||||
|
# --
|
||||||
|
SET GLOBAL log_output = '';
|
||||||
|
ERROR 42000: Variable 'log_output' can't be set to the value of ''
|
||||||
|
SET GLOBAL log_output = 0;
|
||||||
|
ERROR 42000: Variable 'log_output' can't be set to the value of '0'
|
||||||
|
|
||||||
|
# -- End of Bug#34820.
|
||||||
|
@@ -14,8 +14,8 @@ user_limits : Bug#23921 random failure of user_limits.test
|
|||||||
concurrent_innodb : BUG#21579 2006-08-11 mleich innodb_concurrent random failures with varying differences
|
concurrent_innodb : BUG#21579 2006-08-11 mleich innodb_concurrent random failures with varying differences
|
||||||
federated_transactions : Bug#29523 Transactions do not work
|
federated_transactions : Bug#29523 Transactions do not work
|
||||||
lowercase_table3 : Bug#32667 lowercase_table3.test reports to error log
|
lowercase_table3 : Bug#32667 lowercase_table3.test reports to error log
|
||||||
innodb_mysql : Bug#32724: innodb_mysql.test fails randomly
|
|
||||||
ctype_create : Bug#32965 main.ctype_create fails
|
ctype_create : Bug#32965 main.ctype_create fails
|
||||||
status : Bug#32966 main.status fails
|
status : Bug#32966 main.status fails
|
||||||
ps_ddl : Bug#12093 2007-12-14 pending WL#4165 / WL#4166
|
ps_ddl : Bug#12093 2007-12-14 pending WL#4165 / WL#4166
|
||||||
csv_alter_table : Bug#33696 2008-01-21 pcrews no .result file - bug allows NULL columns in CSV tables
|
csv_alter_table : Bug#33696 2008-01-21 pcrews no .result file - bug allows NULL columns in CSV tables
|
||||||
|
cast : Bug#35594 2008-03-27 main.cast fails on Windows2003-64
|
||||||
|
@@ -1266,6 +1266,12 @@ DROP DATABASE db27878;
|
|||||||
use test;
|
use test;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#33275 Server crash when creating temporary table mysql.user
|
||||||
|
--echo #
|
||||||
|
CREATE TEMPORARY TABLE mysql.user (id INT);
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
DROP TABLE mysql.user;
|
||||||
#
|
#
|
||||||
# Bug #33201 Crash occurs when granting update privilege on one column of a view
|
# Bug #33201 Crash occurs when granting update privilege on one column of a view
|
||||||
#
|
#
|
||||||
|
@@ -231,6 +231,34 @@ set global slow_query_log_file= NULL;
|
|||||||
set global general_log_file= @old_general_log_file;
|
set global general_log_file= @old_general_log_file;
|
||||||
set global slow_query_log_file= @old_slow_query_log_file;
|
set global slow_query_log_file= @old_slow_query_log_file;
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo # --
|
||||||
|
--echo # -- Bug#32748: Inconsistent handling of assignments to
|
||||||
|
--echo # -- general_log_file/slow_query_log_file.
|
||||||
|
--echo # --
|
||||||
|
|
||||||
|
--echo
|
||||||
|
SET @general_log_file_saved = @@global.general_log_file;
|
||||||
|
SET @slow_query_log_file_saved = @@global.slow_query_log_file;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
SET GLOBAL general_log_file = 'bug32748.query.log';
|
||||||
|
SET GLOBAL slow_query_log_file = 'bug32748.slow.log';
|
||||||
|
|
||||||
|
--echo
|
||||||
|
SHOW VARIABLES LIKE '%log_file';
|
||||||
|
|
||||||
|
--echo
|
||||||
|
SET GLOBAL general_log_file = @general_log_file_saved;
|
||||||
|
SET GLOBAL slow_query_log_file = @slow_query_log_file_saved;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo # -- End of Bug#32748.
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
|
||||||
--enable_ps_protocol
|
--enable_ps_protocol
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -778,3 +778,20 @@ set global thread_cache_size =@my_thread_cache_size;
|
|||||||
--replace_column 2 #
|
--replace_column 2 #
|
||||||
show global variables where Variable_name='table_definition_cache' or
|
show global variables where Variable_name='table_definition_cache' or
|
||||||
Variable_name='table_lock_wait_timeout';
|
Variable_name='table_lock_wait_timeout';
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo # --
|
||||||
|
--echo # -- Bug#34820: log_output can be set to illegal value.
|
||||||
|
--echo # --
|
||||||
|
|
||||||
|
--error ER_WRONG_VALUE_FOR_VAR
|
||||||
|
SET GLOBAL log_output = '';
|
||||||
|
|
||||||
|
--error ER_WRONG_VALUE_FOR_VAR
|
||||||
|
SET GLOBAL log_output = 0;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo # -- End of Bug#34820.
|
||||||
|
|
||||||
|
@@ -202,7 +202,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
|
|||||||
{
|
{
|
||||||
if (mem_root->error_handler)
|
if (mem_root->error_handler)
|
||||||
(*mem_root->error_handler)();
|
(*mem_root->error_handler)();
|
||||||
return((void*) 0); /* purecov: inspected */
|
DBUG_RETURN((void*) 0); /* purecov: inspected */
|
||||||
}
|
}
|
||||||
mem_root->block_num++;
|
mem_root->block_num++;
|
||||||
next->next= *prev;
|
next->next= *prev;
|
||||||
|
@@ -2314,9 +2314,6 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
|||||||
table deletes.
|
table deletes.
|
||||||
*/
|
*/
|
||||||
if ((thd->lex->sql_command != SQLCOM_DELETE))
|
if ((thd->lex->sql_command != SQLCOM_DELETE))
|
||||||
#ifdef NOT_USED
|
|
||||||
if ((thd->lex->sql_command != SQLCOM_UPDATE))
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Get best non-covering ROR-intersection plan and prepare data for
|
Get best non-covering ROR-intersection plan and prepare data for
|
||||||
|
@@ -1664,6 +1664,14 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
|
|||||||
strmov(buff, "NULL");
|
strmov(buff, "NULL");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_allow_empty_value &&
|
||||||
|
res->length() == 0)
|
||||||
|
{
|
||||||
|
buff[0]= 0;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
var->save_result.ulong_value= ((ulong)
|
var->save_result.ulong_value= ((ulong)
|
||||||
find_set(enum_names, res->c_ptr(),
|
find_set(enum_names, res->c_ptr(),
|
||||||
res->length(),
|
res->length(),
|
||||||
@@ -1679,6 +1687,15 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ulonglong tmp= var->value->val_int();
|
ulonglong tmp= var->value->val_int();
|
||||||
|
|
||||||
|
if (!m_allow_empty_value &&
|
||||||
|
tmp == 0)
|
||||||
|
{
|
||||||
|
buff[0]= '0';
|
||||||
|
buff[1]= 0;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
For when the enum is made to contain 64 elements, as 1ULL<<64 is
|
For when the enum is made to contain 64 elements, as 1ULL<<64 is
|
||||||
undefined, we guard with a "count<64" test.
|
undefined, we guard with a "count<64" test.
|
||||||
@@ -2382,6 +2399,7 @@ static int sys_check_log_path(THD *thd, set_var *var)
|
|||||||
MY_STAT f_stat;
|
MY_STAT f_stat;
|
||||||
String str(buff, sizeof(buff), system_charset_info), *res;
|
String str(buff, sizeof(buff), system_charset_info), *res;
|
||||||
const char *log_file_str;
|
const char *log_file_str;
|
||||||
|
size_t path_length;
|
||||||
|
|
||||||
if (!(res= var->value->val_str(&str)))
|
if (!(res= var->value->val_str(&str)))
|
||||||
goto err;
|
goto err;
|
||||||
@@ -2389,25 +2407,43 @@ static int sys_check_log_path(THD *thd, set_var *var)
|
|||||||
log_file_str= res->c_ptr();
|
log_file_str= res->c_ptr();
|
||||||
bzero(&f_stat, sizeof(MY_STAT));
|
bzero(&f_stat, sizeof(MY_STAT));
|
||||||
|
|
||||||
(void) unpack_filename(path, log_file_str);
|
path_length= unpack_filename(path, log_file_str);
|
||||||
|
|
||||||
|
if (!path_length)
|
||||||
|
{
|
||||||
|
/* File name is empty. */
|
||||||
|
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
if (my_stat(path, &f_stat, MYF(0)))
|
if (my_stat(path, &f_stat, MYF(0)))
|
||||||
{
|
{
|
||||||
/* Check if argument is a file and we have 'write' permission */
|
/*
|
||||||
|
A file system object exists. Check if argument is a file and we have
|
||||||
|
'write' permission.
|
||||||
|
*/
|
||||||
|
|
||||||
if (!MY_S_ISREG(f_stat.st_mode) ||
|
if (!MY_S_ISREG(f_stat.st_mode) ||
|
||||||
!(f_stat.st_mode & MY_S_IWRITE))
|
!(f_stat.st_mode & MY_S_IWRITE))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
/* Get dirname of the file path. */
|
||||||
size_t path_length;
|
|
||||||
/*
|
|
||||||
Check if directory exists and
|
|
||||||
we have permission to create file & write to file
|
|
||||||
*/
|
|
||||||
(void) dirname_part(path, log_file_str, &path_length);
|
(void) dirname_part(path, log_file_str, &path_length);
|
||||||
|
|
||||||
|
/* Dirname is empty if file path is relative. */
|
||||||
|
if (!path_length)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if directory exists and we have permission to create file and
|
||||||
|
write to file.
|
||||||
|
*/
|
||||||
if (my_access(path, (F_OK|W_OK)))
|
if (my_access(path, (F_OK|W_OK)))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
@@ -74,7 +74,8 @@ public:
|
|||||||
sys_var(const char *name_arg, sys_after_update_func func= NULL,
|
sys_var(const char *name_arg, sys_after_update_func func= NULL,
|
||||||
Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
|
Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
|
||||||
:name(name_arg), after_update(func), no_support_one_shot(1),
|
:name(name_arg), after_update(func), no_support_one_shot(1),
|
||||||
binlog_status(binlog_status_arg)
|
binlog_status(binlog_status_arg),
|
||||||
|
m_allow_empty_value(TRUE)
|
||||||
{}
|
{}
|
||||||
virtual ~sys_var() {}
|
virtual ~sys_var() {}
|
||||||
void chain_sys_var(sys_var_chain *chain_arg)
|
void chain_sys_var(sys_var_chain *chain_arg)
|
||||||
@@ -109,8 +110,16 @@ public:
|
|||||||
virtual bool is_readonly() const { return 0; }
|
virtual bool is_readonly() const { return 0; }
|
||||||
virtual sys_var_pluginvar *cast_pluginvar() { return 0; }
|
virtual sys_var_pluginvar *cast_pluginvar() { return 0; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void set_allow_empty_value(bool allow_empty_value)
|
||||||
|
{
|
||||||
|
m_allow_empty_value= allow_empty_value;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Binlog_status_enum binlog_status;
|
const Binlog_status_enum binlog_status;
|
||||||
|
|
||||||
|
bool m_allow_empty_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -878,8 +887,11 @@ public:
|
|||||||
sys_var_log_output(sys_var_chain *chain, const char *name_arg, ulong *value_arg,
|
sys_var_log_output(sys_var_chain *chain, const char *name_arg, ulong *value_arg,
|
||||||
TYPELIB *typelib, sys_after_update_func func)
|
TYPELIB *typelib, sys_after_update_func func)
|
||||||
:sys_var(name_arg,func), value(value_arg), enum_names(typelib)
|
:sys_var(name_arg,func), value(value_arg), enum_names(typelib)
|
||||||
{ chain_sys_var(chain); }
|
{
|
||||||
bool check(THD *thd, set_var *var)
|
chain_sys_var(chain);
|
||||||
|
set_allow_empty_value(FALSE);
|
||||||
|
}
|
||||||
|
virtual bool check(THD *thd, set_var *var)
|
||||||
{
|
{
|
||||||
return check_set(thd, var, enum_names);
|
return check_set(thd, var, enum_names);
|
||||||
}
|
}
|
||||||
|
204
sql/sp.cc
204
sql/sp.cc
@@ -1070,210 +1070,6 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct st_used_field
|
|
||||||
{
|
|
||||||
const char *field_name;
|
|
||||||
uint field_length;
|
|
||||||
enum enum_field_types field_type;
|
|
||||||
Field *field;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct st_used_field init_fields[]=
|
|
||||||
{
|
|
||||||
{ "Db", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0},
|
|
||||||
{ "Name", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0},
|
|
||||||
{ "Type", 9, MYSQL_TYPE_STRING, 0},
|
|
||||||
{ "Definer", USER_HOST_BUFF_SIZE, MYSQL_TYPE_STRING, 0},
|
|
||||||
{ "Modified", 0, MYSQL_TYPE_TIMESTAMP, 0},
|
|
||||||
{ "Created", 0, MYSQL_TYPE_TIMESTAMP, 0},
|
|
||||||
{ "Security_type", 1, MYSQL_TYPE_STRING, 0},
|
|
||||||
{ "Comment", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0},
|
|
||||||
{ "character_set_client", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0},
|
|
||||||
{ "collation_connection", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0},
|
|
||||||
{ "Database Collation", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0},
|
|
||||||
{ 0, 0, MYSQL_TYPE_STRING, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
print_field_values(THD *thd, TABLE *table,
|
|
||||||
struct st_used_field *used_fields,
|
|
||||||
int type, const char *wild)
|
|
||||||
{
|
|
||||||
Protocol *protocol= thd->protocol;
|
|
||||||
|
|
||||||
if (table->field[MYSQL_PROC_MYSQL_TYPE]->val_int() == type)
|
|
||||||
{
|
|
||||||
String db_string;
|
|
||||||
String name_string;
|
|
||||||
struct st_used_field *used_field= used_fields;
|
|
||||||
|
|
||||||
if (get_field(thd->mem_root, used_field->field, &db_string))
|
|
||||||
db_string.set_ascii("", 0);
|
|
||||||
used_field+= 1;
|
|
||||||
get_field(thd->mem_root, used_field->field, &name_string);
|
|
||||||
|
|
||||||
if (!wild || !wild[0] || !wild_compare(name_string.ptr(), wild, 0))
|
|
||||||
{
|
|
||||||
protocol->prepare_for_resend();
|
|
||||||
protocol->store(&db_string);
|
|
||||||
protocol->store(&name_string);
|
|
||||||
for (used_field++;
|
|
||||||
used_field->field_name;
|
|
||||||
used_field++)
|
|
||||||
{
|
|
||||||
switch (used_field->field_type) {
|
|
||||||
case MYSQL_TYPE_TIMESTAMP:
|
|
||||||
{
|
|
||||||
MYSQL_TIME tmp_time;
|
|
||||||
|
|
||||||
bzero((char *)&tmp_time, sizeof(tmp_time));
|
|
||||||
((Field_timestamp *) used_field->field)->get_time(&tmp_time);
|
|
||||||
protocol->store(&tmp_time);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
String tmp_string;
|
|
||||||
|
|
||||||
get_field(thd->mem_root, used_field->field, &tmp_string);
|
|
||||||
protocol->store(&tmp_string);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (protocol->write())
|
|
||||||
return SP_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return SP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Implement SHOW STATUS statement for stored routines.
|
|
||||||
|
|
||||||
@param thd Thread context.
|
|
||||||
@param type Stored routine type
|
|
||||||
(TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION)
|
|
||||||
@param name_pattern Stored routine name pattern.
|
|
||||||
|
|
||||||
@return Error code. SP_OK is returned on success. Other SP_ constants are
|
|
||||||
used to indicate about errors.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
sp_show_status_routine(THD *thd, int type, const char *name_pattern)
|
|
||||||
{
|
|
||||||
TABLE *table;
|
|
||||||
TABLE_LIST tables;
|
|
||||||
int res;
|
|
||||||
DBUG_ENTER("sp_show_status_routine");
|
|
||||||
|
|
||||||
DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
|
|
||||||
type == TYPE_ENUM_FUNCTION);
|
|
||||||
|
|
||||||
memset(&tables, 0, sizeof(tables));
|
|
||||||
tables.db= (char*)"mysql";
|
|
||||||
tables.table_name= tables.alias= (char*)"proc";
|
|
||||||
|
|
||||||
if (! (table= open_ltable(thd, &tables, TL_READ, 0)))
|
|
||||||
{
|
|
||||||
res= SP_OPEN_TABLE_FAILED;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Item *item;
|
|
||||||
List<Item> field_list;
|
|
||||||
struct st_used_field *used_field;
|
|
||||||
TABLE_LIST *leaves= 0;
|
|
||||||
st_used_field used_fields[array_elements(init_fields)];
|
|
||||||
|
|
||||||
table->use_all_columns();
|
|
||||||
memcpy((char*) used_fields, (char*) init_fields, sizeof(used_fields));
|
|
||||||
/* Init header */
|
|
||||||
for (used_field= &used_fields[0];
|
|
||||||
used_field->field_name;
|
|
||||||
used_field++)
|
|
||||||
{
|
|
||||||
switch (used_field->field_type) {
|
|
||||||
case MYSQL_TYPE_TIMESTAMP:
|
|
||||||
item= new Item_return_date_time(used_field->field_name,
|
|
||||||
MYSQL_TYPE_DATETIME);
|
|
||||||
field_list.push_back(item);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
item= new Item_empty_string(used_field->field_name,
|
|
||||||
used_field->field_length);
|
|
||||||
field_list.push_back(item);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Print header */
|
|
||||||
if (thd->protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
|
|
||||||
Protocol::SEND_EOF))
|
|
||||||
{
|
|
||||||
res= SP_INTERNAL_ERROR;
|
|
||||||
goto err_case;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Init fields
|
|
||||||
|
|
||||||
tables is not VIEW for sure => we can pass 0 as condition
|
|
||||||
*/
|
|
||||||
thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
|
|
||||||
setup_tables(thd, &thd->lex->select_lex.context,
|
|
||||||
&thd->lex->select_lex.top_join_list,
|
|
||||||
&tables, &leaves, FALSE);
|
|
||||||
for (used_field= &used_fields[0];
|
|
||||||
used_field->field_name;
|
|
||||||
used_field++)
|
|
||||||
{
|
|
||||||
Item_field *field= new Item_field(&thd->lex->select_lex.context,
|
|
||||||
"mysql", "proc",
|
|
||||||
used_field->field_name);
|
|
||||||
if (!field ||
|
|
||||||
!(used_field->field= find_field_in_tables(thd, field, &tables, NULL,
|
|
||||||
0, REPORT_ALL_ERRORS, 1,
|
|
||||||
TRUE)))
|
|
||||||
{
|
|
||||||
res= SP_INTERNAL_ERROR;
|
|
||||||
goto err_case1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
table->file->ha_index_init(0, 1);
|
|
||||||
if ((res= table->file->index_first(table->record[0])))
|
|
||||||
{
|
|
||||||
res= (res == HA_ERR_END_OF_FILE) ? 0 : SP_INTERNAL_ERROR;
|
|
||||||
goto err_case1;
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
res= print_field_values(thd, table, used_fields, type, name_pattern);
|
|
||||||
|
|
||||||
if (res)
|
|
||||||
goto err_case1;
|
|
||||||
}
|
|
||||||
while (!table->file->index_next(table->record[0]));
|
|
||||||
|
|
||||||
res= SP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_case1:
|
|
||||||
my_eof(thd);
|
|
||||||
err_case:
|
|
||||||
table->file->ha_index_end();
|
|
||||||
close_thread_tables(thd);
|
|
||||||
done:
|
|
||||||
DBUG_RETURN(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Drop all routines in database 'db'
|
Drop all routines in database 'db'
|
||||||
|
|
||||||
|
3
sql/sp.h
3
sql/sp.h
@@ -48,9 +48,6 @@ sp_routine_exists_in_table(THD *thd, int type, sp_name *name);
|
|||||||
bool
|
bool
|
||||||
sp_show_create_routine(THD *thd, int type, sp_name *name);
|
sp_show_create_routine(THD *thd, int type, sp_name *name);
|
||||||
|
|
||||||
int
|
|
||||||
sp_show_status_routine(THD *thd, int type, const char *wild);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
sp_create_routine(THD *thd, int type, sp_head *sp);
|
sp_create_routine(THD *thd, int type, sp_head *sp);
|
||||||
|
|
||||||
|
@@ -695,6 +695,8 @@ my_bool acl_reload(THD *thd)
|
|||||||
tables[0].next_local= tables[0].next_global= tables+1;
|
tables[0].next_local= tables[0].next_global= tables+1;
|
||||||
tables[1].next_local= tables[1].next_global= tables+2;
|
tables[1].next_local= tables[1].next_global= tables+2;
|
||||||
tables[0].lock_type=tables[1].lock_type=tables[2].lock_type=TL_READ;
|
tables[0].lock_type=tables[1].lock_type=tables[2].lock_type=TL_READ;
|
||||||
|
tables[0].skip_temporary= tables[1].skip_temporary=
|
||||||
|
tables[2].skip_temporary= TRUE;
|
||||||
|
|
||||||
if (simple_open_n_lock_tables(thd, tables))
|
if (simple_open_n_lock_tables(thd, tables))
|
||||||
{
|
{
|
||||||
@@ -3537,7 +3539,7 @@ static my_bool grant_load_procs_priv(TABLE *p_table)
|
|||||||
bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
|
bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
|
||||||
MEM_ROOT **save_mem_root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**,
|
MEM_ROOT **save_mem_root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**,
|
||||||
THR_MALLOC);
|
THR_MALLOC);
|
||||||
DBUG_ENTER("grant_load");
|
DBUG_ENTER("grant_load_procs_priv");
|
||||||
(void) hash_init(&proc_priv_hash,system_charset_info,
|
(void) hash_init(&proc_priv_hash,system_charset_info,
|
||||||
0,0,0, (hash_get_key) get_grant_table,
|
0,0,0, (hash_get_key) get_grant_table,
|
||||||
0,0);
|
0,0);
|
||||||
@@ -3721,6 +3723,7 @@ static my_bool grant_reload_procs_priv(THD *thd)
|
|||||||
table.alias= table.table_name= (char*) "procs_priv";
|
table.alias= table.table_name= (char*) "procs_priv";
|
||||||
table.db= (char *) "mysql";
|
table.db= (char *) "mysql";
|
||||||
table.lock_type= TL_READ;
|
table.lock_type= TL_READ;
|
||||||
|
table.skip_temporary= 1;
|
||||||
|
|
||||||
if (simple_open_n_lock_tables(thd, &table))
|
if (simple_open_n_lock_tables(thd, &table))
|
||||||
{
|
{
|
||||||
@@ -3786,7 +3789,7 @@ my_bool grant_reload(THD *thd)
|
|||||||
tables[0].db= tables[1].db= (char *) "mysql";
|
tables[0].db= tables[1].db= (char *) "mysql";
|
||||||
tables[0].next_local= tables[0].next_global= tables+1;
|
tables[0].next_local= tables[0].next_global= tables+1;
|
||||||
tables[0].lock_type= tables[1].lock_type= TL_READ;
|
tables[0].lock_type= tables[1].lock_type= TL_READ;
|
||||||
|
tables[0].skip_temporary= tables[1].skip_temporary= TRUE;
|
||||||
/*
|
/*
|
||||||
To avoid deadlocks we should obtain table locks before
|
To avoid deadlocks we should obtain table locks before
|
||||||
obtaining LOCK_grant rwlock.
|
obtaining LOCK_grant rwlock.
|
||||||
|
@@ -345,26 +345,9 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
|
|||||||
|
|
||||||
if (!(share= alloc_table_share(table_list, key, key_length)))
|
if (!(share= alloc_table_share(table_list, key, key_length)))
|
||||||
{
|
{
|
||||||
#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
|
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
|
||||||
#endif
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
|
|
||||||
// We need a write lock to be able to add a new entry
|
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
|
||||||
pthread_mutex_lock(&LOCK_open);
|
|
||||||
/* Check that another thread didn't insert the same table in between */
|
|
||||||
if ((old_share= hash_search(&table_def_cache, (uchar*) key, key_length)))
|
|
||||||
{
|
|
||||||
(void) pthread_mutex_lock(&share->mutex);
|
|
||||||
free_table_share(share);
|
|
||||||
share= old_share;
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Lock mutex to be able to read table definition from file without
|
Lock mutex to be able to read table definition from file without
|
||||||
conflicts
|
conflicts
|
||||||
@@ -388,29 +371,11 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
|
|||||||
|
|
||||||
if (my_hash_insert(&table_def_cache, (uchar*) share))
|
if (my_hash_insert(&table_def_cache, (uchar*) share))
|
||||||
{
|
{
|
||||||
#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
|
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
|
||||||
(void) pthread_mutex_unlock(&share->mutex);
|
|
||||||
#endif
|
|
||||||
free_table_share(share);
|
free_table_share(share);
|
||||||
DBUG_RETURN(0); // return error
|
DBUG_RETURN(0); // return error
|
||||||
}
|
}
|
||||||
#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
|
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
|
||||||
#endif
|
|
||||||
if (open_table_def(thd, share, db_flags))
|
if (open_table_def(thd, share, db_flags))
|
||||||
{
|
{
|
||||||
#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
|
|
||||||
/*
|
|
||||||
No such table or wrong table definition file
|
|
||||||
Lock first the table cache and then the mutex.
|
|
||||||
This will ensure that no other thread is using the share
|
|
||||||
structure.
|
|
||||||
*/
|
|
||||||
(void) pthread_mutex_unlock(&share->mutex);
|
|
||||||
(void) pthread_mutex_lock(&LOCK_open);
|
|
||||||
(void) pthread_mutex_lock(&share->mutex);
|
|
||||||
#endif
|
|
||||||
*error= share->error;
|
*error= share->error;
|
||||||
(void) hash_delete(&table_def_cache, (uchar*) share);
|
(void) hash_delete(&table_def_cache, (uchar*) share);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
@@ -429,9 +394,6 @@ found:
|
|||||||
|
|
||||||
/* We must do a lock to ensure that the structure is initialized */
|
/* We must do a lock to ensure that the structure is initialized */
|
||||||
(void) pthread_mutex_lock(&share->mutex);
|
(void) pthread_mutex_lock(&share->mutex);
|
||||||
#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
|
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
|
||||||
#endif
|
|
||||||
if (share->error)
|
if (share->error)
|
||||||
{
|
{
|
||||||
/* Table definition contained an error */
|
/* Table definition contained an error */
|
||||||
@@ -618,52 +580,6 @@ void release_table_share(TABLE_SHARE *share, enum release_type type)
|
|||||||
}
|
}
|
||||||
pthread_mutex_unlock(&share->mutex);
|
pthread_mutex_unlock(&share->mutex);
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
|
||||||
|
|
||||||
#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
|
|
||||||
if (to_be_deleted)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
We must try again with new locks as we must get LOCK_open
|
|
||||||
before share->mutex
|
|
||||||
*/
|
|
||||||
pthread_mutex_unlock(&share->mutex);
|
|
||||||
pthread_mutex_lock(&LOCK_open);
|
|
||||||
pthread_mutex_lock(&share->mutex);
|
|
||||||
if (!share->ref_count)
|
|
||||||
{ // No one is using this now
|
|
||||||
TABLE_SHARE *name_lock;
|
|
||||||
if (share->replace_with_name_lock && (name_lock=get_name_lock(share)))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
This code is execured when someone does FLUSH TABLES while on has
|
|
||||||
locked tables.
|
|
||||||
*/
|
|
||||||
(void) hash_search(&def_cache,(uchar*) key,key_length);
|
|
||||||
hash_replace(&def_cache, def_cache.current_record,(uchar*) name_lock);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Remove table definition */
|
|
||||||
hash_delete(&def_cache,(uchar*) share);
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
|
||||||
free_table_share(share);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
|
||||||
if (type == RELEASE_WAIT_FOR_DROP)
|
|
||||||
wait_for_table(share, "Waiting for close");
|
|
||||||
else
|
|
||||||
pthread_mutex_unlock(&share->mutex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (type == RELEASE_WAIT_FOR_DROP)
|
|
||||||
wait_for_table(share, "Waiting for close");
|
|
||||||
else
|
|
||||||
pthread_mutex_unlock(&share->mutex);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -3301,6 +3301,7 @@ end_with_restore_list:
|
|||||||
can free its locks if LOCK TABLES locked some tables before finding
|
can free its locks if LOCK TABLES locked some tables before finding
|
||||||
that it can't lock a table in its list
|
that it can't lock a table in its list
|
||||||
*/
|
*/
|
||||||
|
ha_autocommit_or_rollback(thd, 1);
|
||||||
end_active_trans(thd);
|
end_active_trans(thd);
|
||||||
thd->options&= ~(OPTION_TABLE_LOCK);
|
thd->options&= ~(OPTION_TABLE_LOCK);
|
||||||
}
|
}
|
||||||
@@ -4304,20 +4305,6 @@ create_sp_error:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef NOT_USED
|
|
||||||
case SQLCOM_SHOW_STATUS_PROC:
|
|
||||||
{
|
|
||||||
res= sp_show_status_routine(thd, TYPE_ENUM_PROCEDURE,
|
|
||||||
(lex->wild ? lex->wild->ptr() : NullS));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SQLCOM_SHOW_STATUS_FUNC:
|
|
||||||
{
|
|
||||||
res= sp_show_status_routine(thd, TYPE_ENUM_FUNCTION,
|
|
||||||
(lex->wild ? lex->wild->ptr() : NullS));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
case SQLCOM_SHOW_PROC_CODE:
|
case SQLCOM_SHOW_PROC_CODE:
|
||||||
case SQLCOM_SHOW_FUNC_CODE:
|
case SQLCOM_SHOW_FUNC_CODE:
|
||||||
|
@@ -155,11 +155,11 @@ public:
|
|||||||
virtual void cleanup_stmt();
|
virtual void cleanup_stmt();
|
||||||
bool set_name(LEX_STRING *name);
|
bool set_name(LEX_STRING *name);
|
||||||
inline void close_cursor() { delete cursor; cursor= 0; }
|
inline void close_cursor() { delete cursor; cursor= 0; }
|
||||||
|
inline bool is_in_use() { return flags & (uint) IS_IN_USE; }
|
||||||
bool prepare(const char *packet, uint packet_length);
|
bool prepare(const char *packet, uint packet_length);
|
||||||
bool execute(String *expanded_query, bool open_cursor);
|
bool execute(String *expanded_query, bool open_cursor);
|
||||||
/* Destroy this statement */
|
/* Destroy this statement */
|
||||||
bool deallocate();
|
void deallocate();
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
Store the parsed tree of a prepared statement here.
|
Store the parsed tree of a prepared statement here.
|
||||||
@@ -198,7 +198,7 @@ inline bool is_param_null(const uchar *pos, ulong param_no)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static Prepared_statement *
|
static Prepared_statement *
|
||||||
find_prepared_statement(THD *thd, ulong id, const char *where)
|
find_prepared_statement(THD *thd, ulong id)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
To strictly separate namespaces of SQL prepared statements and C API
|
To strictly separate namespaces of SQL prepared statements and C API
|
||||||
@@ -208,12 +208,8 @@ find_prepared_statement(THD *thd, ulong id, const char *where)
|
|||||||
Statement *stmt= thd->stmt_map.find(id);
|
Statement *stmt= thd->stmt_map.find(id);
|
||||||
|
|
||||||
if (stmt == 0 || stmt->type() != Query_arena::PREPARED_STATEMENT)
|
if (stmt == 0 || stmt->type() != Query_arena::PREPARED_STATEMENT)
|
||||||
{
|
return NULL;
|
||||||
char llbuf[22];
|
|
||||||
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf), llstr(id, llbuf),
|
|
||||||
where);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (Prepared_statement *) stmt;
|
return (Prepared_statement *) stmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2121,10 +2117,15 @@ void mysql_sql_stmt_prepare(THD *thd)
|
|||||||
If there is a statement with the same name, remove it. It is ok to
|
If there is a statement with the same name, remove it. It is ok to
|
||||||
remove old and fail to insert a new one at the same time.
|
remove old and fail to insert a new one at the same time.
|
||||||
*/
|
*/
|
||||||
if (stmt->deallocate())
|
if (stmt->is_in_use())
|
||||||
|
{
|
||||||
|
my_error(ER_PS_NO_RECURSION, MYF(0));
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stmt->deallocate();
|
||||||
|
}
|
||||||
|
|
||||||
if (! (query= get_dynamic_sql_string(lex, &query_len)) ||
|
if (! (query= get_dynamic_sql_string(lex, &query_len)) ||
|
||||||
! (stmt= new Prepared_statement(thd, &thd->protocol_text)))
|
! (stmt= new Prepared_statement(thd, &thd->protocol_text)))
|
||||||
{
|
{
|
||||||
@@ -2320,8 +2321,13 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
|
|||||||
/* First of all clear possible warnings from the previous command */
|
/* First of all clear possible warnings from the previous command */
|
||||||
mysql_reset_thd_for_next_command(thd);
|
mysql_reset_thd_for_next_command(thd);
|
||||||
|
|
||||||
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute")))
|
if (!(stmt= find_prepared_statement(thd, stmt_id)))
|
||||||
|
{
|
||||||
|
char llbuf[22];
|
||||||
|
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
|
||||||
|
llstr(stmt_id, llbuf), "mysql_stmt_execute");
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||||
thd->profiling.set_query_source(stmt->query, stmt->query_length);
|
thd->profiling.set_query_source(stmt->query, stmt->query_length);
|
||||||
@@ -2458,8 +2464,13 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
|
|||||||
/* First of all clear possible warnings from the previous command */
|
/* First of all clear possible warnings from the previous command */
|
||||||
mysql_reset_thd_for_next_command(thd);
|
mysql_reset_thd_for_next_command(thd);
|
||||||
status_var_increment(thd->status_var.com_stmt_fetch);
|
status_var_increment(thd->status_var.com_stmt_fetch);
|
||||||
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_fetch")))
|
if (!(stmt= find_prepared_statement(thd, stmt_id)))
|
||||||
|
{
|
||||||
|
char llbuf[22];
|
||||||
|
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
|
||||||
|
llstr(stmt_id, llbuf), "mysql_stmt_fetch");
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
cursor= stmt->cursor;
|
cursor= stmt->cursor;
|
||||||
if (!cursor)
|
if (!cursor)
|
||||||
@@ -2520,8 +2531,13 @@ void mysql_stmt_reset(THD *thd, char *packet)
|
|||||||
mysql_reset_thd_for_next_command(thd);
|
mysql_reset_thd_for_next_command(thd);
|
||||||
|
|
||||||
status_var_increment(thd->status_var.com_stmt_reset);
|
status_var_increment(thd->status_var.com_stmt_reset);
|
||||||
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset")))
|
if (!(stmt= find_prepared_statement(thd, stmt_id)))
|
||||||
|
{
|
||||||
|
char llbuf[22];
|
||||||
|
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
|
||||||
|
llstr(stmt_id, llbuf), "mysql_stmt_reset");
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
stmt->close_cursor();
|
stmt->close_cursor();
|
||||||
|
|
||||||
@@ -2557,15 +2573,15 @@ void mysql_stmt_close(THD *thd, char *packet)
|
|||||||
|
|
||||||
thd->main_da.disable_status();
|
thd->main_da.disable_status();
|
||||||
|
|
||||||
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_close")))
|
if (!(stmt= find_prepared_statement(thd, stmt_id)))
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The only way currently a statement can be deallocated when it's
|
The only way currently a statement can be deallocated when it's
|
||||||
in use is from within Dynamic SQL.
|
in use is from within Dynamic SQL.
|
||||||
*/
|
*/
|
||||||
DBUG_ASSERT(! (stmt->flags & (uint) Prepared_statement::IS_IN_USE));
|
DBUG_ASSERT(! stmt->is_in_use());
|
||||||
(void) stmt->deallocate();
|
stmt->deallocate();
|
||||||
general_log_print(thd, thd->command, NullS);
|
general_log_print(thd, thd->command, NullS);
|
||||||
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
@@ -2592,14 +2608,15 @@ void mysql_sql_stmt_close(THD *thd)
|
|||||||
name->str));
|
name->str));
|
||||||
|
|
||||||
if (! (stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name)))
|
if (! (stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name)))
|
||||||
{
|
|
||||||
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0),
|
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0),
|
||||||
name->length, name->str, "DEALLOCATE PREPARE");
|
name->length, name->str, "DEALLOCATE PREPARE");
|
||||||
return;
|
else if (stmt->is_in_use())
|
||||||
}
|
my_error(ER_PS_NO_RECURSION, MYF(0));
|
||||||
|
else
|
||||||
if (stmt->deallocate() == 0)
|
{
|
||||||
|
stmt->deallocate();
|
||||||
my_ok(thd);
|
my_ok(thd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2633,17 +2650,13 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
|
|||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
/* Minimal size of long data packet is 6 bytes */
|
/* Minimal size of long data packet is 6 bytes */
|
||||||
if (packet_length < MYSQL_LONG_DATA_HEADER)
|
if (packet_length < MYSQL_LONG_DATA_HEADER)
|
||||||
{
|
|
||||||
my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_send_long_data");
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
stmt_id= uint4korr(packet);
|
stmt_id= uint4korr(packet);
|
||||||
packet+= 4;
|
packet+= 4;
|
||||||
|
|
||||||
if (!(stmt=find_prepared_statement(thd, stmt_id,
|
if (!(stmt=find_prepared_statement(thd, stmt_id)))
|
||||||
"mysql_stmt_send_long_data")))
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
|
||||||
param_number= uint2korr(packet);
|
param_number= uint2korr(packet);
|
||||||
@@ -3186,16 +3199,10 @@ error:
|
|||||||
|
|
||||||
/** Common part of DEALLOCATE PREPARE and mysql_stmt_close. */
|
/** Common part of DEALLOCATE PREPARE and mysql_stmt_close. */
|
||||||
|
|
||||||
bool Prepared_statement::deallocate()
|
void Prepared_statement::deallocate()
|
||||||
{
|
{
|
||||||
/* We account deallocate in the same manner as mysql_stmt_close */
|
/* We account deallocate in the same manner as mysql_stmt_close */
|
||||||
status_var_increment(thd->status_var.com_stmt_close);
|
status_var_increment(thd->status_var.com_stmt_close);
|
||||||
if (flags & (uint) IS_IN_USE)
|
|
||||||
{
|
|
||||||
my_error(ER_PS_NO_RECURSION, MYF(0));
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
/* Statement map calls delete stmt on erase */
|
/* Statement map calls delete stmt on erase */
|
||||||
thd->stmt_map.erase(this);
|
thd->stmt_map.erase(this);
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
@@ -853,8 +853,9 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
|
|||||||
Item **conds, uint order_num, ORDER *order)
|
Item **conds, uint order_num, ORDER *order)
|
||||||
{
|
{
|
||||||
Item *fake_conds= 0;
|
Item *fake_conds= 0;
|
||||||
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
TABLE *table= table_list->table;
|
TABLE *table= table_list->table;
|
||||||
TABLE_LIST tables;
|
#endif
|
||||||
List<Item> all_fields;
|
List<Item> all_fields;
|
||||||
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
||||||
DBUG_ENTER("mysql_prepare_update");
|
DBUG_ENTER("mysql_prepare_update");
|
||||||
@@ -878,9 +879,6 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
|
|||||||
table_list->register_want_access(SELECT_ACL);
|
table_list->register_want_access(SELECT_ACL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bzero((char*) &tables,sizeof(tables)); // For ORDER BY
|
|
||||||
tables.table= table;
|
|
||||||
tables.alias= table_list->alias;
|
|
||||||
thd->lex->allow_sum_func= 0;
|
thd->lex->allow_sum_func= 0;
|
||||||
|
|
||||||
if (setup_tables_and_check_access(thd, &select_lex->context,
|
if (setup_tables_and_check_access(thd, &select_lex->context,
|
||||||
|
@@ -634,6 +634,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
|||||||
my_printf_error(0, "MyISAM table '%s' is in use "
|
my_printf_error(0, "MyISAM table '%s' is in use "
|
||||||
"(most likely by a MERGE table). Try FLUSH TABLES.",
|
"(most likely by a MERGE table). Try FLUSH TABLES.",
|
||||||
MYF(0), name + dirname_length(name));
|
MYF(0), name + dirname_length(name));
|
||||||
|
my_errno= HA_ERR_TABLE_EXIST;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user