Merge weblab.(none):/home/marcsql/TREE/mysql-5.0-8407_b
into weblab.(none):/home/marcsql/TREE/mysql-5.1-8407-merge mysql-test/r/information_schema_db.result: Auto merged mysql-test/r/view.result: Auto merged mysql-test/t/sp.test: Auto merged sql/lock.cc: Auto merged sql/mysqld.cc: Auto merged sql/sp_head.cc: Auto merged sql/sp_head.h: Auto merged sql/sql_base.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_update.cc: Auto merged sql/table.cc: Auto merged sql/table.h: Auto merged
This commit is contained in:
commit
0708859ba8
@ -98,13 +98,13 @@ where table_schema='test';
|
|||||||
table_name table_type table_comment
|
table_name table_type table_comment
|
||||||
t1 BASE TABLE
|
t1 BASE TABLE
|
||||||
v1 VIEW VIEW
|
v1 VIEW VIEW
|
||||||
v2 VIEW View 'test.v2' references invalid table(s) or column(s) or function(s) or define
|
v2 VIEW VIEW
|
||||||
drop table t1;
|
drop table t1;
|
||||||
select table_name, table_type, table_comment from information_schema.tables
|
select table_name, table_type, table_comment from information_schema.tables
|
||||||
where table_schema='test';
|
where table_schema='test';
|
||||||
table_name table_type table_comment
|
table_name table_type table_comment
|
||||||
v1 VIEW View 'test.v1' references invalid table(s) or column(s) or function(s) or define
|
v1 VIEW VIEW
|
||||||
v2 VIEW View 'test.v2' references invalid table(s) or column(s) or function(s) or define
|
v2 VIEW VIEW
|
||||||
drop function f1;
|
drop function f1;
|
||||||
drop function f2;
|
drop function f2;
|
||||||
drop view v1, v2;
|
drop view v1, v2;
|
||||||
|
@ -1935,11 +1935,11 @@ create function f1 () returns int return (select max(col1) from t1);
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CHECK TABLE v1, v2, v3, v4, v5, v6;
|
CHECK TABLE v1, v2, v3, v4, v5, v6;
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.v1 check error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
test.v1 check status OK
|
||||||
test.v2 check status OK
|
test.v2 check status OK
|
||||||
test.v3 check error View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
test.v3 check status OK
|
||||||
test.v4 check status OK
|
test.v4 check status OK
|
||||||
test.v5 check error View 'test.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
test.v5 check status OK
|
||||||
test.v6 check status OK
|
test.v6 check status OK
|
||||||
drop function f1;
|
drop function f1;
|
||||||
drop function f2;
|
drop function f2;
|
||||||
|
@ -1369,7 +1369,7 @@ end|
|
|||||||
select f11()|
|
select f11()|
|
||||||
--error ER_CANT_REOPEN_TABLE
|
--error ER_CANT_REOPEN_TABLE
|
||||||
select f11() from t1|
|
select f11() from t1|
|
||||||
# We don't handle temporary tables used by nested functions well
|
# Test that using a single table instance at a time works
|
||||||
create function f12_1() returns int
|
create function f12_1() returns int
|
||||||
begin
|
begin
|
||||||
drop temporary table if exists t3;
|
drop temporary table if exists t3;
|
||||||
@ -1379,11 +1379,9 @@ begin
|
|||||||
end|
|
end|
|
||||||
create function f12_2() returns int
|
create function f12_2() returns int
|
||||||
return (select count(*) from t3)|
|
return (select count(*) from t3)|
|
||||||
# We need clean start to get error
|
|
||||||
drop temporary table t3|
|
drop temporary table t3|
|
||||||
--error ER_NO_SUCH_TABLE
|
|
||||||
select f12_1()|
|
select f12_1()|
|
||||||
--error ER_NO_SUCH_TABLE
|
|
||||||
select f12_1() from t1 limit 1|
|
select f12_1() from t1 limit 1|
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
@ -6802,6 +6800,53 @@ CALL bug24117()|
|
|||||||
DROP PROCEDURE bug24117|
|
DROP PROCEDURE bug24117|
|
||||||
DROP TABLE t3|
|
DROP TABLE t3|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#8407(Stored functions/triggers ignore exception handler)
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop function if exists func_8407_a|
|
||||||
|
drop function if exists func_8407_b|
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
create function func_8407_a() returns int
|
||||||
|
begin
|
||||||
|
declare x int;
|
||||||
|
|
||||||
|
declare continue handler for sqlexception
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
select 1 from no_such_view limit 1 into x;
|
||||||
|
|
||||||
|
return x;
|
||||||
|
end|
|
||||||
|
|
||||||
|
create function func_8407_b() returns int
|
||||||
|
begin
|
||||||
|
declare x int default 0;
|
||||||
|
|
||||||
|
declare continue handler for sqlstate '42S02'
|
||||||
|
begin
|
||||||
|
set x:= x+1000;
|
||||||
|
end;
|
||||||
|
|
||||||
|
case (select 1 from no_such_view limit 1)
|
||||||
|
when 1 then set x:= x+1;
|
||||||
|
when 2 then set x:= x+2;
|
||||||
|
else set x:= x+100;
|
||||||
|
end case;
|
||||||
|
set x:=x + 500;
|
||||||
|
|
||||||
|
return x;
|
||||||
|
end|
|
||||||
|
|
||||||
|
select func_8407_a()|
|
||||||
|
select func_8407_b()|
|
||||||
|
|
||||||
|
drop function func_8407_a|
|
||||||
|
drop function func_8407_b|
|
||||||
|
|
||||||
#
|
#
|
||||||
# NOTE: The delimiter is `|`, and not `;`. It is changed to `;`
|
# NOTE: The delimiter is `|`, and not `;`. It is changed to `;`
|
||||||
# at the end of the file!
|
# at the end of the file!
|
||||||
|
@ -604,7 +604,7 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
|
|||||||
|
|
||||||
for (; haystack; haystack= haystack->next_global)
|
for (; haystack; haystack= haystack->next_global)
|
||||||
{
|
{
|
||||||
if (haystack->placeholder() || haystack->schema_table)
|
if (haystack->placeholder())
|
||||||
continue;
|
continue;
|
||||||
table2= haystack->table;
|
table2= haystack->table;
|
||||||
if (table2->s->tmp_table == TMP_TABLE)
|
if (table2->s->tmp_table == TMP_TABLE)
|
||||||
|
@ -2553,6 +2553,14 @@ static int my_message_sql(uint error, const char *str, myf MyFlags)
|
|||||||
*/
|
*/
|
||||||
if ((thd= current_thd))
|
if ((thd= current_thd))
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
TODO: There are two exceptions mechanism (THD and sp_rcontext),
|
||||||
|
this could be improved by having a common stack of handlers.
|
||||||
|
*/
|
||||||
|
if (thd->handle_error(error,
|
||||||
|
MYSQL_ERROR::WARN_LEVEL_ERROR))
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
if (thd->spcont &&
|
if (thd->spcont &&
|
||||||
thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd))
|
thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd))
|
||||||
{
|
{
|
||||||
|
@ -2444,16 +2444,11 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
|||||||
m_lex->mark_as_requiring_prelocking(lex_query_tables_own_last);
|
m_lex->mark_as_requiring_prelocking(lex_query_tables_own_last);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reinit_stmt_before_use(thd, m_lex);
|
reinit_stmt_before_use(thd, m_lex);
|
||||||
/*
|
|
||||||
If requested check whenever we have access to tables in LEX's table list
|
if (open_tables)
|
||||||
and open and lock them before executing instructtions core function.
|
res= instr->exec_open_and_lock_tables(thd, m_lex->query_tables, nextp);
|
||||||
*/
|
|
||||||
if (open_tables &&
|
|
||||||
(check_table_access(thd, SELECT_ACL, m_lex->query_tables, 0) ||
|
|
||||||
open_and_lock_tables(thd, m_lex->query_tables)))
|
|
||||||
res= -1;
|
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
@ -2505,6 +2500,33 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
|||||||
sp_instr class functions
|
sp_instr class functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
int sp_instr::exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables,
|
||||||
|
uint *nextp)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check whenever we have access to tables for this statement
|
||||||
|
and open and lock them before executing instructions core function.
|
||||||
|
*/
|
||||||
|
if (check_table_access(thd, SELECT_ACL, tables, 0)
|
||||||
|
|| open_and_lock_tables(thd, tables))
|
||||||
|
{
|
||||||
|
get_cont_dest(nextp);
|
||||||
|
result= -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result= 0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sp_instr::get_cont_dest(uint *nextp)
|
||||||
|
{
|
||||||
|
*nextp= m_ip+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int sp_instr::exec_core(THD *thd, uint *nextp)
|
int sp_instr::exec_core(THD *thd, uint *nextp)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
@ -2690,6 +2712,15 @@ sp_instr_set_trigger_field::print(String *str)
|
|||||||
value->print(str);
|
value->print(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
sp_instr_opt_meta
|
||||||
|
*/
|
||||||
|
|
||||||
|
void sp_instr_opt_meta::get_cont_dest(uint *nextp)
|
||||||
|
{
|
||||||
|
*nextp= m_cont_dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
sp_instr_jump class functions
|
sp_instr_jump class functions
|
||||||
|
@ -477,6 +477,28 @@ public:
|
|||||||
|
|
||||||
virtual int execute(THD *thd, uint *nextp) = 0;
|
virtual int execute(THD *thd, uint *nextp) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Execute <code>open_and_lock_tables()</code> for this statement.
|
||||||
|
Open and lock the tables used by this statement, as a pre-requisite
|
||||||
|
to execute the core logic of this instruction with
|
||||||
|
<code>exec_core()</code>.
|
||||||
|
If this statement fails, the next instruction to execute is also returned.
|
||||||
|
This is useful when a user defined SQL continue handler needs to be
|
||||||
|
executed.
|
||||||
|
@param thd the current thread
|
||||||
|
@param tables the list of tables to open and lock
|
||||||
|
@param nextp the continuation instruction, returned to the caller if this
|
||||||
|
method fails.
|
||||||
|
@return zero on success, non zero on failure.
|
||||||
|
*/
|
||||||
|
int exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables, uint *nextp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the continuation destination of this instruction.
|
||||||
|
@param nextp the continuation destination (output)
|
||||||
|
*/
|
||||||
|
virtual void get_cont_dest(uint *nextp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Execute core function of instruction after all preparations (e.g.
|
Execute core function of instruction after all preparations (e.g.
|
||||||
setting of proper LEX, saving part of the thread context have been
|
setting of proper LEX, saving part of the thread context have been
|
||||||
@ -741,6 +763,8 @@ public:
|
|||||||
virtual void set_destination(uint old_dest, uint new_dest)
|
virtual void set_destination(uint old_dest, uint new_dest)
|
||||||
= 0;
|
= 0;
|
||||||
|
|
||||||
|
virtual void get_cont_dest(uint *nextp);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
sp_instr *m_optdest; // Used during optimization
|
sp_instr *m_optdest; // Used during optimization
|
||||||
|
102
sql/sql_base.cc
102
sql/sql_base.cc
@ -28,6 +28,59 @@
|
|||||||
#include <io.h>
|
#include <io.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
This internal handler is used to trap internally
|
||||||
|
errors that can occur when executing open table
|
||||||
|
during the prelocking phase.
|
||||||
|
*/
|
||||||
|
class Prelock_error_handler : public Internal_error_handler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Prelock_error_handler()
|
||||||
|
: m_handled_errors(0), m_unhandled_errors(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual ~Prelock_error_handler() {}
|
||||||
|
|
||||||
|
virtual bool handle_error(uint sql_errno,
|
||||||
|
MYSQL_ERROR::enum_warning_level level,
|
||||||
|
THD *thd);
|
||||||
|
|
||||||
|
bool safely_trapped_errors();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_handled_errors;
|
||||||
|
int m_unhandled_errors;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Prelock_error_handler::handle_error(uint sql_errno,
|
||||||
|
MYSQL_ERROR::enum_warning_level /* level */,
|
||||||
|
THD * /* thd */)
|
||||||
|
{
|
||||||
|
if (sql_errno == ER_NO_SUCH_TABLE)
|
||||||
|
{
|
||||||
|
m_handled_errors++;
|
||||||
|
return TRUE; // 'TRUE', as per coding style
|
||||||
|
}
|
||||||
|
|
||||||
|
m_unhandled_errors++;
|
||||||
|
return FALSE; // 'FALSE', as per coding style
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Prelock_error_handler::safely_trapped_errors()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
If m_unhandled_errors != 0, something else, unanticipated, happened,
|
||||||
|
so the error is not trapped but returned to the caller.
|
||||||
|
Multiple ER_NO_SUCH_TABLE can be raised in case of views.
|
||||||
|
*/
|
||||||
|
return ((m_handled_errors > 0) && (m_unhandled_errors == 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TABLE *unused_tables; /* Used by mysql_test */
|
TABLE *unused_tables; /* Used by mysql_test */
|
||||||
HASH open_cache; /* Used by mysql_test */
|
HASH open_cache; /* Used by mysql_test */
|
||||||
static HASH table_def_cache;
|
static HASH table_def_cache;
|
||||||
@ -1977,7 +2030,10 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias);
|
if ((thd->locked_tables) && (thd->locked_tables->lock_count > 0))
|
||||||
|
my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias);
|
||||||
|
else
|
||||||
|
my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2860,6 +2916,8 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||||||
MEM_ROOT new_frm_mem;
|
MEM_ROOT new_frm_mem;
|
||||||
/* Also used for indicating that prelocking is need */
|
/* Also used for indicating that prelocking is need */
|
||||||
TABLE_LIST **query_tables_last_own;
|
TABLE_LIST **query_tables_last_own;
|
||||||
|
bool safe_to_ignore_table;
|
||||||
|
|
||||||
DBUG_ENTER("open_tables");
|
DBUG_ENTER("open_tables");
|
||||||
/*
|
/*
|
||||||
temporary mem_root for new .frm parsing.
|
temporary mem_root for new .frm parsing.
|
||||||
@ -2908,6 +2966,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||||||
|
|
||||||
for (tables= *start; tables ;tables= tables->next_global)
|
for (tables= *start; tables ;tables= tables->next_global)
|
||||||
{
|
{
|
||||||
|
safe_to_ignore_table= FALSE; // 'FALSE', as per coding style
|
||||||
/*
|
/*
|
||||||
Ignore placeholders for derived tables. After derived tables
|
Ignore placeholders for derived tables. After derived tables
|
||||||
processing, link to created temporary table will be put here.
|
processing, link to created temporary table will be put here.
|
||||||
@ -2927,9 +2986,28 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
(*counter)++;
|
(*counter)++;
|
||||||
|
|
||||||
if (!tables->table &&
|
if (!tables->table)
|
||||||
!(tables->table= open_table(thd, tables, &new_frm_mem, &refresh, flags)))
|
{
|
||||||
|
if (tables->prelocking_placeholder)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
For the tables added by the pre-locking code, attempt to open
|
||||||
|
the table but fail silently if the table does not exist.
|
||||||
|
The real failure will occur when/if a statement attempts to use
|
||||||
|
that table.
|
||||||
|
*/
|
||||||
|
Prelock_error_handler prelock_handler;
|
||||||
|
thd->push_internal_handler(& prelock_handler);
|
||||||
|
tables->table= open_table(thd, tables, &new_frm_mem, &refresh, flags);
|
||||||
|
thd->pop_internal_handler();
|
||||||
|
safe_to_ignore_table= prelock_handler.safely_trapped_errors();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tables->table= open_table(thd, tables, &new_frm_mem, &refresh, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tables->table)
|
||||||
{
|
{
|
||||||
free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC));
|
free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC));
|
||||||
|
|
||||||
@ -2980,6 +3058,14 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||||||
close_tables_for_reopen(thd, start);
|
close_tables_for_reopen(thd, start);
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (safe_to_ignore_table)
|
||||||
|
{
|
||||||
|
DBUG_PRINT("info", ("open_table: ignoring table '%s'.'%s'",
|
||||||
|
tables->db, tables->alias));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
result= -1; // Fatal error
|
result= -1; // Fatal error
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3283,7 +3369,7 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags)
|
|||||||
static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table)
|
static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table)
|
||||||
{
|
{
|
||||||
for (; table; table= table->next_global)
|
for (; table; table= table->next_global)
|
||||||
if (!table->placeholder() && !table->schema_table)
|
if (!table->placeholder())
|
||||||
table->table->query_id= 0;
|
table->table->query_id= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3356,7 +3442,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
|
|||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
for (table= tables; table; table= table->next_global)
|
for (table= tables; table; table= table->next_global)
|
||||||
{
|
{
|
||||||
if (!table->placeholder() && !table->schema_table)
|
if (!table->placeholder())
|
||||||
*(ptr++)= table->table;
|
*(ptr++)= table->table;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3409,7 +3495,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
|
|||||||
|
|
||||||
for (table= tables; table != first_not_own; table= table->next_global)
|
for (table= tables; table != first_not_own; table= table->next_global)
|
||||||
{
|
{
|
||||||
if (!table->placeholder() && !table->schema_table)
|
if (!table->placeholder())
|
||||||
{
|
{
|
||||||
table->table->query_id= thd->query_id;
|
table->table->query_id= thd->query_id;
|
||||||
if (check_lock_and_start_stmt(thd, table->table, table->lock_type))
|
if (check_lock_and_start_stmt(thd, table->table, table->lock_type))
|
||||||
@ -3436,7 +3522,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
|
|||||||
TABLE_LIST *first_not_own= thd->lex->first_not_own_table();
|
TABLE_LIST *first_not_own= thd->lex->first_not_own_table();
|
||||||
for (table= tables; table != first_not_own; table= table->next_global)
|
for (table= tables; table != first_not_own; table= table->next_global)
|
||||||
{
|
{
|
||||||
if (!table->placeholder() && !table->schema_table &&
|
if (!table->placeholder() &&
|
||||||
check_lock_and_start_stmt(thd, table->table, table->lock_type))
|
check_lock_and_start_stmt(thd, table->table, table->lock_type))
|
||||||
{
|
{
|
||||||
ha_rollback_stmt(thd);
|
ha_rollback_stmt(thd);
|
||||||
|
@ -309,6 +309,38 @@ THD::THD()
|
|||||||
substitute_null_with_insert_id = FALSE;
|
substitute_null_with_insert_id = FALSE;
|
||||||
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
|
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
|
||||||
thr_lock_owner_init(&main_lock_id, &lock_info);
|
thr_lock_owner_init(&main_lock_id, &lock_info);
|
||||||
|
|
||||||
|
m_internal_handler= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void THD::push_internal_handler(Internal_error_handler *handler)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
TODO: The current implementation is limited to 1 handler at a time only.
|
||||||
|
THD and sp_rcontext need to be modified to use a common handler stack.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(m_internal_handler == NULL);
|
||||||
|
m_internal_handler= handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool THD::handle_error(uint sql_errno,
|
||||||
|
MYSQL_ERROR::enum_warning_level level)
|
||||||
|
{
|
||||||
|
if (m_internal_handler)
|
||||||
|
{
|
||||||
|
return m_internal_handler->handle_error(sql_errno, level, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE; // 'FALSE', as per coding style
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void THD::pop_internal_handler()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(m_internal_handler != NULL);
|
||||||
|
m_internal_handler= NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -907,7 +907,7 @@ reopen_tables:
|
|||||||
tl->lock_type= using_update_log ? TL_READ_NO_INSERT : TL_READ;
|
tl->lock_type= using_update_log ? TL_READ_NO_INSERT : TL_READ;
|
||||||
tl->updating= 0;
|
tl->updating= 0;
|
||||||
/* Update TABLE::lock_type accordingly. */
|
/* Update TABLE::lock_type accordingly. */
|
||||||
if (!tl->placeholder() && !tl->schema_table && !using_lock_tables)
|
if (!tl->placeholder() && !using_lock_tables)
|
||||||
tl->table->reginfo.lock_type= tl->lock_type;
|
tl->table->reginfo.lock_type= tl->lock_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2890,7 +2890,9 @@ void st_table_list::hide_view_error(THD *thd)
|
|||||||
thd->net.last_errno == ER_SP_DOES_NOT_EXIST ||
|
thd->net.last_errno == ER_SP_DOES_NOT_EXIST ||
|
||||||
thd->net.last_errno == ER_PROCACCESS_DENIED_ERROR ||
|
thd->net.last_errno == ER_PROCACCESS_DENIED_ERROR ||
|
||||||
thd->net.last_errno == ER_COLUMNACCESS_DENIED_ERROR ||
|
thd->net.last_errno == ER_COLUMNACCESS_DENIED_ERROR ||
|
||||||
thd->net.last_errno == ER_TABLEACCESS_DENIED_ERROR)
|
thd->net.last_errno == ER_TABLEACCESS_DENIED_ERROR ||
|
||||||
|
thd->net.last_errno == ER_TABLE_NOT_LOCKED ||
|
||||||
|
thd->net.last_errno == ER_NO_SUCH_TABLE)
|
||||||
{
|
{
|
||||||
TABLE_LIST *top= top_table();
|
TABLE_LIST *top= top_table();
|
||||||
thd->clear_error();
|
thd->clear_error();
|
||||||
|
@ -856,7 +856,7 @@ typedef struct st_table_list
|
|||||||
int view_check_option(THD *thd, bool ignore_failure);
|
int view_check_option(THD *thd, bool ignore_failure);
|
||||||
bool setup_underlying(THD *thd);
|
bool setup_underlying(THD *thd);
|
||||||
void cleanup_items();
|
void cleanup_items();
|
||||||
bool placeholder() {return derived || view; }
|
bool placeholder() {return derived || view || schema_table || !table; }
|
||||||
void print(THD *thd, String *str);
|
void print(THD *thd, String *str);
|
||||||
bool check_single_table(st_table_list **table, table_map map,
|
bool check_single_table(st_table_list **table, table_map map,
|
||||||
st_table_list *view);
|
st_table_list *view);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user