Below is the list of changes that have just been committed into a local
5.1 repository of marcsql. When marcsql does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-03-06 13:51:16-07:00, malff@weblab.(none) +3 -0
Merge malff@stripped:/home/bk/mysql-5.1-runtime
into weblab.(none):/home/marcsql/TREE/mysql-5.1-8407-merge
MERGE: 1.2451.1.2
sql/sp_head.cc@stripped, 2007-03-06 13:48:05-07:00, malff@weblab.(none) +0 -0
Auto merged
MERGE: 1.254.1.1
sql/sql_base.cc@stripped, 2007-03-06 13:51:14-07:00, malff@weblab.(none) +4 -0
Manual merge
MERGE: 1.379.1.1
sql/sql_class.cc@stripped, 2007-03-06 13:48:06-07:00, malff@weblab.(none) +0 -0
Auto merged
MERGE: 1.315.1.1
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: malff
# Host: weblab.(none)
# Root: /home/marcsql/TREE/mysql-5.1-8407-merge/RESYNC
--- 1.380/sql/sql_base.cc 2007-03-06 13:51:23 -07:00
+++ 1.381/sql/sql_base.cc 2007-03-06 13:51:23 -07:00
@@ -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;
@@ -1997,7 +2050,10 @@ TABLE *open_table(THD *thd, TABLE_LIST *
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);
}
@@ -2950,6 +3006,8 @@ int open_tables(THD *thd, TABLE_LIST **s
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.
@@ -3002,6 +3060,7 @@ int open_tables(THD *thd, TABLE_LIST **s
*/
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.
@@ -3032,8 +3091,27 @@ int open_tables(THD *thd, TABLE_LIST **s
Not a placeholder: must be a base table or a view, and the table is
not opened yet. Try to open the table.
*/
- 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));
@@ -3084,6 +3162,14 @@ int open_tables(THD *thd, TABLE_LIST **s
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;
}
@@ -3387,7 +3473,7 @@ bool open_normal_and_derived_tables(THD
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;
}
@@ -3460,7 +3546,7 @@ int lock_tables(THD *thd, TABLE_LIST *ta
DBUG_RETURN(-1);
for (table= tables; table; table= table->next_global)
{
- if (!table->placeholder() && !table->schema_table)
+ if (!table->placeholder())
*(ptr++)= table->table;
}
@@ -3513,7 +3599,7 @@ int lock_tables(THD *thd, TABLE_LIST *ta
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))
@@ -3540,7 +3626,7 @@ int lock_tables(THD *thd, TABLE_LIST *ta
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);
--- 1.316/sql/sql_class.cc 2007-03-06 13:51:23 -07:00
+++ 1.317/sql/sql_class.cc 2007-03-06 13:51:23 -07:00
@@ -309,6 +309,38 @@ THD::THD()
substitute_null_with_insert_id = FALSE;
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
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;
}
--- 1.255/sql/sp_head.cc 2007-03-06 13:51:23 -07:00
+++ 1.256/sql/sp_head.cc 2007-03-06 13:51:23 -07:00
@@ -2444,16 +2444,11 @@ sp_lex_keeper::reset_lex_and_exec_core(T
m_lex->mark_as_requiring_prelocking(lex_query_tables_own_last);
}
}
-
+
reinit_stmt_before_use(thd, m_lex);
- /*
- If requested check whenever we have access to tables in LEX's table list
- and open and lock them before executing instructtions core function.
- */
- 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 (open_tables)
+ res= instr->exec_open_and_lock_tables(thd, m_lex->query_tables, nextp);
if (!res)
{
@@ -2505,6 +2500,33 @@ sp_lex_keeper::reset_lex_and_exec_core(T
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)
{
DBUG_ASSERT(0);
@@ -2688,6 +2710,15 @@ sp_instr_set_trigger_field::print(String
trigger_field->print(str);
str->append(STRING_WITH_LEN(":="));
value->print(str);
+}
+
+/*
+ sp_instr_opt_meta
+*/
+
+void sp_instr_opt_meta::get_cont_dest(uint *nextp)
+{
+ *nextp= m_cont_dest;
}
| Thread |
|---|
| • bk commit into 5.1 tree (malff:1.2454) | marc.alff | 6 Mar |