diff options
author | unknown <bell@sanja.is.com.ua> | 2004-11-05 17:29:47 +0200 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2004-11-05 17:29:47 +0200 |
commit | 8b0ece5e88de965aeb2af410d193bf8c6d96dcde (patch) | |
tree | 7c3c0f2fa9d3f0ef56c352118e5174450230fec2 /sql/sql_derived.cc | |
parent | e981c836104675533a2eb6810f7c1606377b0491 (diff) | |
download | mariadb-git-8b0ece5e88de965aeb2af410d193bf8c6d96dcde.tar.gz |
new lock for multiupdate:
- open and create derived tables
- detect which tables should be locked for write
- lock and fill derived tables
some unitialized variables fixed
mysql-test/r/lock_multi.result:
correct results returned
mysql-test/r/multi_update.result:
correct results returned
mysql-test/r/view.result:
correct results returned
mysql-test/t/multi_update.test:
correct results returned
mysql-test/t/view.test:
correct results returned
sql/mysql_priv.h:
derived tables processing splited on table creation and table filling
sql/sql_base.cc:
derived tables processing splited on table creation and table filling
sql/sql_class.h:
function to detect when we need fill derived tables
sql/sql_derived.cc:
derived tables processing splited on table creation and table filling
sql/sql_lex.cc:
fixed uninitialized value
sql/sql_load.cc:
fixed uninitialized value
sql/sql_parse.cc:
initialization muved (will be done for all queries)
sql/sql_prepare.cc:
preparation of multiupdate changed a bit because new locking procedure
sql/sql_update.cc:
new lock for multiupdate:
- open and create derived tables
- detect which tables should be locked for write
- lock and fill derived tables
sql/table.h:
place to store select_result between creation and filling tables
Diffstat (limited to 'sql/sql_derived.cc')
-rw-r--r-- | sql/sql_derived.cc | 236 |
1 files changed, 135 insertions, 101 deletions
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 0923cf811f5..10ef6a081b6 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -25,15 +25,15 @@ #include "sql_select.h" #include "sql_acl.h" -static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, - TABLE_LIST *t); + /* - Resolve derived tables in all queries + call given derived table processor (preparing or filling tables) SYNOPSIS mysql_handle_derived() lex LEX for this thread + processor procedure of derived table processing RETURN 0 ok @@ -42,7 +42,7 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, */ int -mysql_handle_derived(LEX *lex) +mysql_handle_derived(LEX *lex, int (*processor)(THD*, LEX*, TABLE_LIST*)) { if (lex->derived_tables) { @@ -55,14 +55,8 @@ mysql_handle_derived(LEX *lex) cursor= cursor->next_local) { int res; - if (cursor->derived && (res= mysql_derived(lex->thd, lex, - cursor->derived, - cursor))) - { + if ((res= (*processor)(lex->thd, lex, cursor))) return res; - } - else if (cursor->ancestor) - cursor->set_ancestor(); } if (lex->describe) { @@ -80,20 +74,16 @@ mysql_handle_derived(LEX *lex) /* - Resolve derived tables in all queries + Create temporary table structure (but do not fill it) SYNOPSIS mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) thd Thread handle lex LEX for this thread - unit node that contains all SELECT's for derived tables - t TABLE_LIST for the upper SELECT + orig_table_list 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. After table creation, the above TABLE_LIST is updated with a new table. @@ -107,60 +97,126 @@ mysql_handle_derived(LEX *lex) 0 ok 1 Error -1 Error and error message given -*/ - + */ -static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, - TABLE_LIST *org_table_list) +int mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list) { - SELECT_LEX *first_select= unit->first_select(); - TABLE *table; - int res; - select_union *derived_result; - bool is_union= first_select->next_select() && - first_select->next_select()->linkage == UNION_TYPE; - SELECT_LEX *save_current_select= lex->current_select; - DBUG_ENTER("mysql_derived"); - - if (!(derived_result= new select_union(0))) - DBUG_RETURN(1); // out of memory - - // st_select_lex_unit::prepare correctly work for single select - if ((res= unit->prepare(thd, derived_result, 0))) - goto exit; - - - derived_result->tmp_table_param.init(); - derived_result->tmp_table_param.field_count= unit->types.elements; - /* - Temp table is created so that it hounours if UNION without ALL is to be - processed - */ - if (!(table= create_tmp_table(thd, &derived_result->tmp_table_param, - unit->types, (ORDER*) 0, - is_union && unit->union_distinct, 1, - (first_select->options | thd->options | - TMP_TABLE_ALL_COLUMNS), - HA_POS_ERROR, - org_table_list->alias))) + SELECT_LEX_UNIT *unit= orig_table_list->derived; + int res= 0; + if (unit) { - res= -1; - goto exit; + SELECT_LEX *first_select= unit->first_select(); + TABLE *table= 0; + select_union *derived_result; + bool is_union= first_select->next_select() && + first_select->next_select()->linkage == UNION_TYPE; + DBUG_ENTER("mysql_derived"); + + if (!(derived_result= new select_union(0))) + DBUG_RETURN(1); // out of memory + + // st_select_lex_unit::prepare correctly work for single select + if ((res= unit->prepare(thd, derived_result, 0))) + goto exit; + + + derived_result->tmp_table_param.init(); + derived_result->tmp_table_param.field_count= unit->types.elements; + /* + Temp table is created so that it hounours if UNION without ALL is to be + processed + */ + if (!(table= create_tmp_table(thd, &derived_result->tmp_table_param, + unit->types, (ORDER*) 0, + is_union && unit->union_distinct, 1, + (first_select->options | thd->options | + TMP_TABLE_ALL_COLUMNS), + HA_POS_ERROR, + orig_table_list->alias))) + { + res= -1; + goto exit; + } + derived_result->set_table(table); + +exit: + /* + if it is preparation PS only or commands that need only VIEW structure + then we do not need real data and we can skip execution (and parameters + is not defined, too) + */ + if (res) + { + if (table) + free_tmp_table(thd, table); + delete derived_result; + } + else + { + if (!thd->fill_derived_tables()) + delete derived_result; + orig_table_list->derived_result= derived_result; + orig_table_list->table= table; + orig_table_list->real_name= table->real_name; + table->derived_select_number= first_select->select_number; + table->tmp_table= TMP_TABLE; +#ifndef NO_EMBEDDED_ACCESS_CHECKS + table->grant.privilege= SELECT_ACL; +#endif + orig_table_list->db= (char *)""; + // Force read of table stats in the optimizer + table->file->info(HA_STATUS_VARIABLE); + /* Add new temporary table to list of open derived tables */ + table->next= thd->derived_tables; + thd->derived_tables= table; + } } - derived_result->set_table(table); + else if (orig_table_list->ancestor) + orig_table_list->set_ancestor(); + return (res); +} + - /* - if it is preparation PS only or commands that need only VIEW structure - then we do not need real data and we can skip execution (and parameters - is not defined, too) +/* + fill derived table + + SYNOPSIS + mysql_derived_filling() + thd Thread handle + lex LEX for this thread + unit node that contains all SELECT's for derived tables + orig_table_list 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 filled, 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. + + RETURN + 0 ok + 1 Error + -1 Error and error message given */ - if (!thd->only_prepare() && !lex->only_view_structure()) + +int mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *orig_table_list) +{ + TABLE *table= orig_table_list->table; + SELECT_LEX_UNIT *unit= orig_table_list->derived; + int res= 0; + + /*check that table creation pass without problem and it is derived table */ + if (table && unit) { + SELECT_LEX *first_select= unit->first_select(); + select_union *derived_result= orig_table_list->derived_result; + SELECT_LEX *save_current_select= lex->current_select; + bool is_union= first_select->next_select() && + first_select->next_select()->linkage == UNION_TYPE; if (is_union) { // execute union without clean up - if (!(res= unit->prepare(thd, derived_result, SELECT_NO_UNLOCK))) - res= unit->exec(); + res= unit->exec(); } else { @@ -173,7 +229,7 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, first_select->options&= ~OPTION_FOUND_ROWS; lex->current_select= first_select; - res= mysql_select(thd, &first_select->ref_pointer_array, + res= mysql_select(thd, &first_select->ref_pointer_array, (TABLE_LIST*) first_select->table_list.first, first_select->with_wild, first_select->item_list, first_select->where, @@ -186,49 +242,27 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, SELECT_NO_UNLOCK), derived_result, unit, first_select); } - } - if (!res) - { - /* - Here we entirely fix both TABLE_LIST and list of SELECT's as - there were no derived tables - */ - if (derived_result->flush()) - res= 1; - else + if (!res) { - org_table_list->real_name= table->real_name; - org_table_list->table= table; - table->derived_select_number= first_select->select_number; - table->tmp_table= TMP_TABLE; -#ifndef NO_EMBEDDED_ACCESS_CHECKS - table->grant.privilege= SELECT_ACL; -#endif - org_table_list->db= (char *)""; - // Force read of table stats in the optimizer - table->file->info(HA_STATUS_VARIABLE); - } + /* + Here we entirely fix both TABLE_LIST and list of SELECT's as + there were no derived tables + */ + if (derived_result->flush()) + res= 1; - if (!lex->describe) - unit->cleanup(); - if (res) - free_tmp_table(thd, table); + if (!lex->describe) + unit->cleanup(); + } else { - /* Add new temporary table to list of open derived tables */ - table->next= thd->derived_tables; - thd->derived_tables= table; + free_tmp_table(thd, table); + unit->cleanup(); } + lex->current_select= save_current_select; + if (res) + free_tmp_table(thd, table); } - else - { - free_tmp_table(thd, table); - unit->cleanup(); - } - -exit: - delete derived_result; - lex->current_select= save_current_select; - DBUG_RETURN(res); + return res; } |