summaryrefslogtreecommitdiff
path: root/sql/sql_base.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r--sql/sql_base.cc135
1 files changed, 105 insertions, 30 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 02ecb158ebe..8f319ee645d 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1305,9 +1305,9 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
goto err; // Can't repair the table
TABLE_LIST table_list;
+ bzero((char*) &table_list, sizeof(table_list)); // just for safe
table_list.db=(char*) db;
table_list.real_name=(char*) name;
- table_list.next=0;
safe_mutex_assert_owner(&LOCK_open);
if ((error=lock_table_name(thd,&table_list)))
@@ -1356,27 +1356,45 @@ err:
DBUG_RETURN(1);
}
-/*****************************************************************************
-** open all tables in list
-*****************************************************************************/
+/*
+ Open all tables in list
-int open_tables(THD *thd,TABLE_LIST *start)
+ SYNOPSIS
+ open_tables()
+ thd - thread handler
+ start - list of tables
+ counter - number of opened tables will be return using this parameter
+
+ RETURN
+ 0 - OK
+ -1 - error
+*/
+
+int open_tables(THD *thd, TABLE_LIST *start, uint *counter)
{
TABLE_LIST *tables;
bool refresh;
int result=0;
DBUG_ENTER("open_tables");
+ *counter= 0;
thd->current_tablenr= 0;
restart:
thd->proc_info="Opening tables";
for (tables=start ; tables ; tables=tables->next)
{
+ /*
+ Ignore placeholders for derived tables. After derived tables
+ processing, link to created temporary table will be put here.
+ */
+ if (tables->derived)
+ continue;
+ (*counter)++;
if (!tables->table &&
- !(tables->table=open_table(thd,
- tables->db,
- tables->real_name,
- tables->alias, &refresh)))
+ !(tables->table= open_table(thd,
+ tables->db,
+ tables->real_name,
+ tables->alias, &refresh)))
{
if (refresh) // Refresh in progress
{
@@ -1522,15 +1540,57 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
/*
- Open all tables in list and locks them for read.
- The lock will automaticly be freed by close_thread_tables()
+ Open all tables in list and locks them for read without derived
+ tables processing.
+
+ SYNOPSIS
+ simple_open_n_lock_tables()
+ thd - thread handler
+ tables - list of tables for open&locking
+
+ RETURN
+ 0 - ok
+ -1 - error
+
+ NOTE
+ The lock will automaticly be freed by close_thread_tables()
*/
-int open_and_lock_tables(THD *thd,TABLE_LIST *tables)
+int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables)
{
- if (open_tables(thd,tables) || lock_tables(thd,tables))
- return -1; /* purecov: inspected */
- return 0;
+ DBUG_ENTER("simple_open_n_lock_tables");
+ uint counter;
+ if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter))
+ DBUG_RETURN(-1); /* purecov: inspected */
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Open all tables in list, locks them and process derived tables
+ tables processing.
+
+ SYNOPSIS
+ open_and_lock_tables()
+ thd - thread handler
+ tables - list of tables for open&locking
+
+ RETURN
+ 0 - ok
+ -1 - error
+
+ NOTE
+ The lock will automaticly be freed by close_thread_tables()
+*/
+
+int open_and_lock_tables(THD *thd, TABLE_LIST *tables)
+{
+ DBUG_ENTER("open_and_lock_tables");
+ uint counter;
+ if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter))
+ DBUG_RETURN(-1); /* purecov: inspected */
+ fix_tables_pointers(thd->lex->all_selects_list);
+ DBUG_RETURN(mysql_handle_derived(thd->lex));
}
@@ -1541,6 +1601,7 @@ int open_and_lock_tables(THD *thd,TABLE_LIST *tables)
lock_tables()
thd Thread handler
tables Tables to lock
+ count umber of opened tables
NOTES
You can't call lock_tables twice, as this would break the dead-lock-free
@@ -1552,7 +1613,7 @@ int open_and_lock_tables(THD *thd,TABLE_LIST *tables)
-1 Error
*/
-int lock_tables(THD *thd,TABLE_LIST *tables)
+int lock_tables(THD *thd, TABLE_LIST *tables, uint count)
{
TABLE_LIST *table;
if (!tables)
@@ -1561,14 +1622,14 @@ int lock_tables(THD *thd,TABLE_LIST *tables)
if (!thd->locked_tables)
{
DBUG_ASSERT(thd->lock == 0); // You must lock everything at once
- uint count=0;
- for (table = tables ; table ; table=table->next)
- count++;
TABLE **start,**ptr;
if (!(ptr=start=(TABLE**) sql_alloc(sizeof(TABLE*)*count)))
return -1;
for (table = tables ; table ; table=table->next)
- *(ptr++)= table->table;
+ {
+ if (!table->derived)
+ *(ptr++)= table->table;
+ }
if (!(thd->lock=mysql_lock_tables(thd,start,count)))
return -1; /* purecov: inspected */
}
@@ -1576,7 +1637,8 @@ int lock_tables(THD *thd,TABLE_LIST *tables)
{
for (table = tables ; table ; table=table->next)
{
- if (check_lock_and_start_stmt(thd, table->table, table->lock_type))
+ if (!table->derived &&
+ check_lock_and_start_stmt(thd, table->table, table->lock_type))
{
ha_rollback_stmt(thd);
return -1;
@@ -2039,15 +2101,28 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
/*
- Remap table numbers if INSERT ... SELECT
- Check also that the 'used keys' and 'ignored keys' exists and set up the
- table structure accordingly
+ prepare tables
+
+ SYNOPSIS
+ setup_tables()
+ tables - tables list
+ reinit - true if called for table reinitialization before
+ subquery reexecuting
+
+ RETURN
+ 0 ok; In this case *map will includes the choosed index
+ 1 error
+
+ NOTE
+ Remap table numbers if INSERT ... SELECT
+ Check also that the 'used keys' and 'ignored keys' exists and set up the
+ table structure accordingly
- This has to be called for all tables that are used by items, as otherwise
- table->map is not set and all Item_field will be regarded as const items.
+ This has to be called for all tables that are used by items, as otherwise
+ table->map is not set and all Item_field will be regarded as const items.
*/
-bool setup_tables(TABLE_LIST *tables)
+bool setup_tables(TABLE_LIST *tables, my_bool reinit)
{
DBUG_ENTER("setup_tables");
uint tablenr=0;
@@ -2074,7 +2149,7 @@ bool setup_tables(TABLE_LIST *tables)
table->keys_in_use_for_query.subtract(map);
}
table->used_keys.intersect(table->keys_in_use_for_query);
- if (table_list->shared || table->clear_query_id)
+ if ((table_list->shared || table->clear_query_id) && !reinit)
{
table->clear_query_id= 0;
/* Clear query_id that may have been set by previous select */
@@ -2382,7 +2457,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
create_info.default_table_charset= thd->variables.collation_database;
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
&create_info, table_list,
- fields, keys, drop, alter, 0, (ORDER*)0, FALSE,
+ fields, keys, drop, alter, 0, (ORDER*)0,
DUP_ERROR));
}
@@ -2399,7 +2474,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
create_info.default_table_charset= thd->variables.collation_database;
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
&create_info, table_list,
- fields, keys, drop, alter, 0, (ORDER*)0, FALSE,
+ fields, keys, drop, alter, 0, (ORDER*)0,
DUP_ERROR));
}