mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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:
102
sql/sql_base.cc
102
sql/sql_base.cc
@ -28,6 +28,59 @@
|
||||
#include <io.h>
|
||||
#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 */
|
||||
HASH open_cache; /* Used by mysql_test */
|
||||
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));
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@ -2860,6 +2916,8 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
||||
MEM_ROOT new_frm_mem;
|
||||
/* Also used for indicating that prelocking is need */
|
||||
TABLE_LIST **query_tables_last_own;
|
||||
bool safe_to_ignore_table;
|
||||
|
||||
DBUG_ENTER("open_tables");
|
||||
/*
|
||||
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)
|
||||
{
|
||||
safe_to_ignore_table= FALSE; // 'FALSE', as per coding style
|
||||
/*
|
||||
Ignore placeholders for derived tables. After derived tables
|
||||
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);
|
||||
}
|
||||
(*counter)++;
|
||||
|
||||
if (!tables->table &&
|
||||
!(tables->table= open_table(thd, tables, &new_frm_mem, &refresh, flags)))
|
||||
|
||||
if (!tables->table)
|
||||
{
|
||||
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));
|
||||
|
||||
@ -2980,6 +3058,14 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
||||
close_tables_for_reopen(thd, start);
|
||||
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
|
||||
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)
|
||||
{
|
||||
for (; table; table= table->next_global)
|
||||
if (!table->placeholder() && !table->schema_table)
|
||||
if (!table->placeholder())
|
||||
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);
|
||||
for (table= tables; table; table= table->next_global)
|
||||
{
|
||||
if (!table->placeholder() && !table->schema_table)
|
||||
if (!table->placeholder())
|
||||
*(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)
|
||||
{
|
||||
if (!table->placeholder() && !table->schema_table)
|
||||
if (!table->placeholder())
|
||||
{
|
||||
table->table->query_id= thd->query_id;
|
||||
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();
|
||||
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))
|
||||
{
|
||||
ha_rollback_stmt(thd);
|
||||
|
Reference in New Issue
Block a user