summaryrefslogtreecommitdiff
path: root/sql/sql_base.cc
diff options
context:
space:
mode:
authorcmiller@zippy.cornsilk.net <>2007-11-09 14:55:32 -0500
committercmiller@zippy.cornsilk.net <>2007-11-09 14:55:32 -0500
commit1426320008b7d17497d0e3c802ccf9b94c20e032 (patch)
tree80d51cbfd49ff9e193edbb78843eb3e2ebbae2c9 /sql/sql_base.cc
parentf12087af5886e46d458471a0d61b3703d128918f (diff)
parent6921dd0156939aa8d9230d8690c2eb47d2342d8a (diff)
downloadmariadb-git-1426320008b7d17497d0e3c802ccf9b94c20e032.tar.gz
Merge bk-internal.mysql.com:/home/bk/mysql-5.1-community
into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.1-forcollapseandmerge
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r--sql/sql_base.cc156
1 files changed, 97 insertions, 59 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index c4c860c48f4..ed0ddbbd15d 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -44,7 +44,7 @@ public:
virtual ~Prelock_error_handler() {}
- virtual bool handle_error(uint sql_errno,
+ virtual bool handle_error(uint sql_errno, const char *message,
MYSQL_ERROR::enum_warning_level level,
THD *thd);
@@ -58,6 +58,7 @@ private:
bool
Prelock_error_handler::handle_error(uint sql_errno,
+ const char * /* message */,
MYSQL_ERROR::enum_warning_level /* level */,
THD * /* thd */)
{
@@ -1054,6 +1055,29 @@ bool close_cached_connection_tables(THD *thd, bool if_wait_for_refresh,
}
+/**
+ Mark all temporary tables which were used by the current statement or
+ substatement as free for reuse, but only if the query_id can be cleared.
+
+ @param thd thread context
+
+ @remark For temp tables associated with a open SQL HANDLER the query_id
+ is not reset until the HANDLER is closed.
+*/
+
+static void mark_temp_tables_as_free_for_reuse(THD *thd)
+{
+ for (TABLE *table= thd->temporary_tables ; table ; table= table->next)
+ {
+ if ((table->query_id == thd->query_id) && ! table->open_by_handler)
+ {
+ table->query_id= 0;
+ table->file->ha_reset();
+ }
+ }
+}
+
+
/*
Mark all tables in the list which were used by current substatement
as free for reuse.
@@ -1090,6 +1114,42 @@ static void mark_used_tables_as_free_for_reuse(THD *thd, TABLE *table)
}
+/**
+ Auxiliary function to close all tables in the open_tables list.
+
+ @param thd Thread context.
+
+ @remark It should not ordinarily be called directly.
+*/
+
+static void close_open_tables(THD *thd)
+{
+ bool found_old_table= 0;
+
+ safe_mutex_assert_not_owner(&LOCK_open);
+
+ VOID(pthread_mutex_lock(&LOCK_open));
+
+ DBUG_PRINT("info", ("thd->open_tables: 0x%lx", (long) thd->open_tables));
+
+ while (thd->open_tables)
+ found_old_table|= close_thread_table(thd, &thd->open_tables);
+ thd->some_tables_deleted= 0;
+
+ /* Free tables to hold down open files */
+ while (open_cache.records > table_cache_size && unused_tables)
+ VOID(hash_delete(&open_cache,(uchar*) unused_tables)); /* purecov: tested */
+ check_unused();
+ if (found_old_table)
+ {
+ /* Tell threads waiting for refresh that something has happened */
+ broadcast_refresh();
+ }
+
+ VOID(pthread_mutex_unlock(&LOCK_open));
+}
+
+
/*
Close all tables used by the current substatement, or all tables
used by this thread if we are on the upper level.
@@ -1097,26 +1157,19 @@ static void mark_used_tables_as_free_for_reuse(THD *thd, TABLE *table)
SYNOPSIS
close_thread_tables()
thd Thread handler
- lock_in_use Set to 1 (0 = default) if caller has a lock on
- LOCK_open
- skip_derived Set to 1 (0 = default) if we should not free derived
- tables.
- stopper When closing tables from thd->open_tables(->next)*,
- don't close/remove tables starting from stopper.
IMPLEMENTATION
Unlocks tables and frees derived tables.
Put all normal tables used by thread in free list.
- When in prelocked mode it will only close/mark as free for reuse
- tables opened by this substatement, it will also check if we are
- closing tables after execution of complete query (i.e. we are on
- upper level) and will leave prelocked mode if needed.
+ It will only close/mark as free for reuse tables opened by this
+ substatement, it will also check if we are closing tables after
+ execution of complete query (i.e. we are on upper level) and will
+ leave prelocked mode if needed.
*/
-void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
+void close_thread_tables(THD *thd)
{
- bool found_old_table;
prelocked_mode_type prelocked_mode= thd->prelocked_mode;
DBUG_ENTER("close_thread_tables");
@@ -1131,7 +1184,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
derived tables with (sub-)statement instead of thread and destroy
them at the end of its execution.
*/
- if (thd->derived_tables && !skip_derived)
+ if (thd->derived_tables)
{
TABLE *table, *next;
/*
@@ -1146,13 +1199,10 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
thd->derived_tables= 0;
}
- if (prelocked_mode)
- {
- /*
- Mark all temporary tables used by this substatement as free for reuse.
- */
- mark_used_tables_as_free_for_reuse(thd, thd->temporary_tables);
- }
+ /*
+ Mark all temporary tables used by this statement as free for reuse.
+ */
+ mark_temp_tables_as_free_for_reuse(thd);
if (thd->locked_tables || prelocked_mode)
{
@@ -1216,28 +1266,8 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
if (!thd->active_transaction())
thd->transaction.xid_state.xid.null();
- if (!lock_in_use)
- VOID(pthread_mutex_lock(&LOCK_open));
-
- DBUG_PRINT("info", ("thd->open_tables: 0x%lx", (long) thd->open_tables));
-
- found_old_table= 0;
- while (thd->open_tables)
- found_old_table|= close_thread_table(thd, &thd->open_tables);
- thd->some_tables_deleted=0;
-
- /* Free tables to hold down open files */
- while (open_cache.records > table_cache_size && unused_tables)
- VOID(hash_delete(&open_cache,(uchar*) unused_tables)); /* purecov: tested */
- check_unused();
- if (found_old_table)
- {
- /* Tell threads waiting for refresh that something has happened */
- broadcast_refresh();
- }
- if (!lock_in_use)
- VOID(pthread_mutex_unlock(&LOCK_open));
- /* VOID(pthread_sigmask(SIG_SETMASK,&thd->signals,NULL)); */
+ if (thd->open_tables)
+ close_open_tables(thd);
if (prelocked_mode == PRELOCKED)
{
@@ -1674,6 +1704,7 @@ TABLE *find_temporary_table(THD *thd, TABLE_LIST *table_list)
Try to locate the table in the list of thd->temporary_tables.
If the table is found:
+ - if the table is being used by some outer statement, fail.
- if the table is in thd->locked_tables, unlock it and
remove it from the list of locked tables. Currently only transactional
temporary tables are present in the locked_tables list.
@@ -1688,24 +1719,34 @@ TABLE *find_temporary_table(THD *thd, TABLE_LIST *table_list)
thd->temporary_tables list, it's impossible to tell here whether
we're dealing with an internal or a user temporary table.
- @retval TRUE the table was not found in the list of temporary tables
- of this thread
- @retval FALSE the table was found and dropped successfully.
+ @retval 0 the table was found and dropped successfully.
+ @retval 1 the table was not found in the list of temporary tables
+ of this thread
+ @retval -1 the table is in use by a outer query
*/
-bool close_temporary_table(THD *thd, TABLE_LIST *table_list)
+int drop_temporary_table(THD *thd, TABLE_LIST *table_list)
{
TABLE *table;
+ DBUG_ENTER("drop_temporary_table");
if (!(table= find_temporary_table(thd, table_list)))
- return 1;
+ DBUG_RETURN(1);
+
+ /* Table might be in use by some outer statement. */
+ if (table->query_id && table->query_id != thd->query_id)
+ {
+ my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
+ DBUG_RETURN(-1);
+ }
+
/*
If LOCK TABLES list is not empty and contains this table,
unlock the table and remove the table from this list.
*/
mysql_lock_remove(thd, thd->locked_tables, table, FALSE);
close_temporary_table(thd, table, 1, 1);
- return 0;
+ DBUG_RETURN(0);
}
/*
@@ -2284,8 +2325,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
is always represented by only one TABLE object in THD, and
it can not be cloned. Emit an error for an unsupported behaviour.
*/
- if (table->query_id == thd->query_id ||
- thd->prelocked_mode && table->query_id)
+ if (table->query_id)
{
DBUG_PRINT("error",
("query_id: %lu server_id: %u pseudo_thread_id: %lu",
@@ -2295,7 +2335,6 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
DBUG_RETURN(0);
}
table->query_id= thd->query_id;
- table->clear_query_id= 1;
thd->thread_specific_used= TRUE;
DBUG_PRINT("info",("Using temporary table"));
goto reset;
@@ -4305,7 +4344,6 @@ void close_tables_for_reopen(THD *thd, TABLE_LIST **tables)
sp_remove_not_own_routines(thd->lex);
for (TABLE_LIST *tmp= *tables; tmp; tmp= tmp->next_global)
tmp->table= 0;
- mark_used_tables_as_free_for_reuse(thd, thd->temporary_tables);
close_thread_tables(thd);
}
@@ -6260,7 +6298,7 @@ bool setup_fields(THD *thd, Item **ref_pointer_array,
thd->lex->allow_sum_func= save_allow_sum_func;
thd->mark_used_columns= save_mark_used_columns;
DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
- DBUG_RETURN(test(thd->net.report_error));
+ DBUG_RETURN(test(thd->is_error()));
}
@@ -6804,7 +6842,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
select_lex->conds_processed_with_permanent_arena= 1;
}
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
- DBUG_RETURN(test(thd->net.report_error));
+ DBUG_RETURN(test(thd->is_error()));
err_no_arena:
select_lex->is_item_list_lookup= save_is_item_list_lookup;
@@ -6886,7 +6924,7 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
goto err;
}
}
- DBUG_RETURN(thd->net.report_error);
+ DBUG_RETURN(thd->is_error());
err:
if (table)
table->auto_increment_field_not_null= FALSE;
@@ -6971,7 +7009,7 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors)
table= (*ptr)->table;
table->auto_increment_field_not_null= FALSE;
}
- while ((field = *ptr++) && !thd->net.report_error)
+ while ((field = *ptr++) && ! thd->is_error())
{
value=v++;
table= field->table;
@@ -6980,7 +7018,7 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors)
if (value->save_in_field(field, 0) < 0)
goto err;
}
- DBUG_RETURN(thd->net.report_error);
+ DBUG_RETURN(thd->is_error());
err:
if (table)
@@ -7390,7 +7428,7 @@ open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias,
else
{
/* only VIEWs are supported now */
- my_error(ER_FRM_UNKNOWN_TYPE, MYF(0), share->path, parser->type()->str);
+ my_error(ER_FRM_UNKNOWN_TYPE, MYF(0), share->path.str, parser->type()->str);
goto err;
}
DBUG_RETURN(0);