mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Fixed that derived tables are properly droped
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2000 MySQL AB
|
||||
/* Copyright (C) 2002-2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
/*
|
||||
Derived tables
|
||||
These were introduced by Monty and Sinisa <sinisa@mysql.com>
|
||||
These were introduced by Sinisa <sinisa@mysql.com>
|
||||
*/
|
||||
|
||||
|
||||
@ -38,17 +38,26 @@ static const char *any_db="*any*"; // Special symbol for check_access
|
||||
t TABLE_LIST for the upper SELECT
|
||||
|
||||
IMPLEMENTATION
|
||||
|
||||
Derived table is resolved with temporary table. It is created based on the
|
||||
queries defined. After temporary table is created, if this is not EXPLAIN,
|
||||
then the entire unit / node is deleted. unit is deleted if UNION is used
|
||||
for derived table and node is deleted is it is a simple SELECT.
|
||||
Derived table is resolved with temporary table. It is created based on the
|
||||
queries defined. After temporary table is created, if this is not EXPLAIN,
|
||||
then the entire unit / node is deleted. unit is deleted if UNION is used
|
||||
for derived table and node is deleted is it is a simple SELECT.
|
||||
|
||||
After table creation, the above TABLE_LIST is updated with a new table.
|
||||
After table creation, the above TABLE_LIST is updated with a new table.
|
||||
|
||||
This function is called before any command containing derived table is executed.
|
||||
This function is called before any command containing derived table
|
||||
is executed.
|
||||
|
||||
TODO: To move creation of derived tables IN open_and_lock_tables()
|
||||
Derived tables is stored in thd->derived_tables and freed in
|
||||
close_thread_tables()
|
||||
|
||||
TODO
|
||||
Move creation of derived tables in open_and_lock_tables()
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
1 Error
|
||||
-1 Error and error message given
|
||||
*/
|
||||
|
||||
|
||||
@ -57,21 +66,21 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
|
||||
SELECT_LEX *sl= unit->first_select();
|
||||
List<Item> item_list;
|
||||
TABLE *table;
|
||||
int res= 0;
|
||||
int res;
|
||||
select_union *derived_result;
|
||||
TABLE_LIST *tables= (TABLE_LIST *)sl->table_list.first;
|
||||
TMP_TABLE_PARAM tmp_table_param;
|
||||
bool is_union=sl->next_select() && sl->next_select()->linkage == UNION_TYPE;
|
||||
DBUG_ENTER("mysql_derived");
|
||||
SELECT_LEX_NODE *save_current_select= lex->current_select;
|
||||
DBUG_ENTER("mysql_derived");
|
||||
|
||||
|
||||
/*
|
||||
In create_total_list, derived tables have to be treated in case of EXPLAIN,
|
||||
This is because unit/node is not deleted in that case. Current code in this
|
||||
function has to be improved to recognize better when this function is called
|
||||
from derived tables and when from other functions.
|
||||
*/
|
||||
/*
|
||||
In create_total_list, derived tables have to be treated in case of
|
||||
EXPLAIN, This is because unit/node is not deleted in that
|
||||
case. Current code in this function has to be improved to
|
||||
recognize better when this function is called from derived tables
|
||||
and when from other functions.
|
||||
*/
|
||||
if (is_union && unit->create_total_list(thd, lex, &tables))
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
@ -92,30 +101,21 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
|
||||
{
|
||||
if (is_union)
|
||||
{
|
||||
/*
|
||||
The following code is a re-do of fix_tables_pointers() found in sql_select.cc
|
||||
for UNION's within derived tables. The only difference is in navigation, as in
|
||||
derived tables we care for this level only.
|
||||
/*
|
||||
The following code is a re-do of fix_tables_pointers() found
|
||||
in sql_select.cc for UNION's within derived tables. The only
|
||||
difference is in navigation, as in derived tables we care for
|
||||
this level only.
|
||||
|
||||
fix_tables_pointers makes sure that in UNION's we do not open single table twice
|
||||
if found in different SELECT's.
|
||||
|
||||
*/
|
||||
for (SELECT_LEX *sel= sl;
|
||||
sel;
|
||||
sel= sel->next_select())
|
||||
{
|
||||
for (TABLE_LIST *cursor= (TABLE_LIST *)sel->table_list.first;
|
||||
cursor;
|
||||
cursor=cursor->next)
|
||||
cursor->table= cursor->table_list->table;
|
||||
}
|
||||
*/
|
||||
for (SELECT_LEX *sel= sl; sel; sel= sel->next_select())
|
||||
relink_tables(sel);
|
||||
}
|
||||
|
||||
lex->current_select= sl;
|
||||
if (setup_fields(thd,tables,item_list,0,0,1))
|
||||
{
|
||||
res=-1;
|
||||
res= -1;
|
||||
goto exit;
|
||||
}
|
||||
bzero((char*) &tmp_table_param,sizeof(tmp_table_param));
|
||||
@ -127,7 +127,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
|
||||
TMP_TABLE_ALL_COLUMNS),
|
||||
HA_POS_ERROR)))
|
||||
{
|
||||
res=-1;
|
||||
res= -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
|
||||
sl->options&= ~OPTION_FOUND_ROWS;
|
||||
|
||||
if (is_union)
|
||||
res=mysql_union(thd,lex,derived_result,unit);
|
||||
res= mysql_union(thd,lex,derived_result,unit);
|
||||
else
|
||||
res= mysql_select(thd, tables, sl->item_list,
|
||||
sl->where, (ORDER *) sl->order_list.first,
|
||||
@ -153,9 +153,12 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
|
||||
|
||||
if (!res)
|
||||
{
|
||||
// Here we entirely fix both TABLE_LIST and list of SELECT's as there were no derived tables
|
||||
/*
|
||||
Here we entirely fix both TABLE_LIST and list of SELECT's as
|
||||
there were no derived tables
|
||||
*/
|
||||
if (derived_result->flush())
|
||||
res=1;
|
||||
res= 1;
|
||||
else
|
||||
{
|
||||
t->real_name=table->real_name;
|
||||
@ -164,23 +167,29 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
|
||||
table->tmp_table=TMP_TABLE;
|
||||
if (lex->describe)
|
||||
{
|
||||
// to fix a problem in EXPLAIN
|
||||
if (tables)
|
||||
tables->table_list->table=tables->table; // to fix a problem in EXPLAIN
|
||||
tables->table_list->table=tables->table;
|
||||
}
|
||||
else
|
||||
unit->exclude();
|
||||
t->db=(char *)"";
|
||||
t->derived=(SELECT_LEX *)1; // just in case ...
|
||||
t->db= (char *)"";
|
||||
t->derived=(SELECT_LEX *) 1; // just in case ...
|
||||
table->file->info(HA_STATUS_VARIABLE);
|
||||
}
|
||||
}
|
||||
delete derived_result;
|
||||
}
|
||||
if (res)
|
||||
free_tmp_table(thd,table);
|
||||
free_tmp_table(thd, table);
|
||||
else
|
||||
{
|
||||
table->next= thd->derived_tables;
|
||||
thd->derived_tables= table;
|
||||
}
|
||||
exit:
|
||||
lex->current_select= save_current_select;
|
||||
close_thread_tables(thd);
|
||||
close_thread_tables(thd, 0, 1);
|
||||
}
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
Reference in New Issue
Block a user