summaryrefslogtreecommitdiff
path: root/sql/sql_derived.cc
diff options
context:
space:
mode:
authorunknown <monty@mashka.mysql.fi>2003-01-07 11:45:06 +0200
committerunknown <monty@mashka.mysql.fi>2003-01-07 11:45:06 +0200
commit64dc734dee09157bf0c4c9bd84ba6b16754e27e1 (patch)
treeabb09346d74f5eb8cf867ea184e544bab1f41331 /sql/sql_derived.cc
parentef62b4c948d68108c0945ebde33540b03b392a6d (diff)
downloadmariadb-git-64dc734dee09157bf0c4c9bd84ba6b16754e27e1.tar.gz
Fixed that derived tables are properly droped
mysys/my_init.c: Move my_once_free() up to not get warnings for this from safemalloc. sql/item_row.cc: Removed compiler warnings sql/sql_select.cc: split fix_tables_pointer() into two functions to be able to reuse code sql/sql_select.h: split fix_tables_pointer() into two functions to be able to reuse code
Diffstat (limited to 'sql/sql_derived.cc')
-rw-r--r--sql/sql_derived.cc103
1 files changed, 56 insertions, 47 deletions
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 1ddaedeb480..0a2e2947add 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -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.
+ Derived tables is stored in thd->derived_tables and freed in
+ close_thread_tables()
- TODO: To move creation of derived tables IN open_and_lock_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.
-
- 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;
- }
+ /*
+ 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.
+
+ */
+ 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);
}