summaryrefslogtreecommitdiff
path: root/sql/sql_union.cc
diff options
context:
space:
mode:
authorbell@sanja.is.com.ua <>2003-05-14 21:51:33 +0300
committerbell@sanja.is.com.ua <>2003-05-14 21:51:33 +0300
commit19156321637e68fc16714af83be1892bedb8c2c9 (patch)
treedd5bbcb7c0561f00a367fdeab1296efdea9012ca /sql/sql_union.cc
parent8bb08c512d829b84977beb120f64cd67ca9dd0a0 (diff)
downloadmariadb-git-19156321637e68fc16714af83be1892bedb8c2c9.tar.gz
subselect transformation moved in after-fix_field place
removed "of is null" if it is possible (this cset should be SCRUM related, but not approved as scrum task yet)
Diffstat (limited to 'sql/sql_union.cc')
-rw-r--r--sql/sql_union.cc112
1 files changed, 58 insertions, 54 deletions
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index fe4ca49da14..44ee4898433 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -188,42 +188,33 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result,
union_result->not_describe=1;
union_result->tmp_table_param=tmp_table_param;
- /*
- The following piece of code is placed here solely for the purpose of
- getting correct results with EXPLAIN when UNION is withing a sub-select
- or derived table ...
- */
-
- if (thd->lex.describe)
+ for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
{
- for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
- {
- JOIN *join= new JOIN(thd, sl->item_list,
- sl->options | thd->options | SELECT_NO_UNLOCK,
- union_result);
- thd->lex.current_select= sl;
- offset_limit_cnt= sl->offset_limit;
- select_limit_cnt= sl->select_limit+sl->offset_limit;
- if (select_limit_cnt < sl->select_limit)
- select_limit_cnt= HA_POS_ERROR; // no limit
- if (select_limit_cnt == HA_POS_ERROR)
- sl->options&= ~OPTION_FOUND_ROWS;
-
- res= join->prepare(&sl->ref_pointer_array,
- (TABLE_LIST*) sl->table_list.first, sl->with_wild,
- sl->where,
- ((sl->braces) ? sl->order_list.elements : 0) +
- sl->group_list.elements,
- (sl->braces) ?
- (ORDER *)sl->order_list.first : (ORDER *) 0,
- (ORDER*) sl->group_list.first,
- sl->having,
- (ORDER*) NULL,
- sl, this, t_and_f);
- t_and_f= 0;
- if (res || thd->is_fatal_error)
- goto err;
- }
+ JOIN *join= new JOIN(thd, sl->item_list,
+ sl->options | thd->options | SELECT_NO_UNLOCK,
+ union_result);
+ thd->lex.current_select= sl;
+ offset_limit_cnt= sl->offset_limit;
+ select_limit_cnt= sl->select_limit+sl->offset_limit;
+ if (select_limit_cnt < sl->select_limit)
+ select_limit_cnt= HA_POS_ERROR; // no limit
+ if (select_limit_cnt == HA_POS_ERROR)
+ sl->options&= ~OPTION_FOUND_ROWS;
+
+ res= join->prepare(&sl->ref_pointer_array,
+ (TABLE_LIST*) sl->table_list.first, sl->with_wild,
+ sl->where,
+ ((sl->braces) ? sl->order_list.elements : 0) +
+ sl->group_list.elements,
+ (sl->braces) ?
+ (ORDER *)sl->order_list.first : (ORDER *) 0,
+ (ORDER*) sl->group_list.first,
+ sl->having,
+ (ORDER*) NULL,
+ sl, this, t_and_f);
+ t_and_f= 0;
+ if (res || thd->is_fatal_error)
+ goto err;
}
item_list.empty();
@@ -268,14 +259,12 @@ int st_select_lex_unit::exec()
}
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
{
+ thd->lex.current_select= sl;
+
if (optimized)
res= sl->join->reinit();
else
{
- JOIN *join= new JOIN(thd, sl->item_list,
- sl->options | thd->options | SELECT_NO_UNLOCK,
- union_result);
- thd->lex.current_select= sl;
offset_limit_cnt= sl->offset_limit;
select_limit_cnt= sl->select_limit+sl->offset_limit;
if (select_limit_cnt < sl->select_limit)
@@ -283,22 +272,36 @@ int st_select_lex_unit::exec()
if (select_limit_cnt == HA_POS_ERROR)
sl->options&= ~OPTION_FOUND_ROWS;
- res= join->prepare(&sl->ref_pointer_array,
- (TABLE_LIST*) sl->table_list.first, sl->with_wild,
- sl->where,
- ((sl->braces) ? sl->order_list.elements : 0) +
- sl->group_list.elements,
- (sl->braces) ?
- (ORDER *)sl->order_list.first : (ORDER *) 0,
- (ORDER*) sl->group_list.first,
- sl->having,
- (ORDER*) NULL,
- sl, this, t_and_f);
- t_and_f=0;
- if (res | thd->is_fatal_error)
+ /*
+ As far as union share table space we should reassign table map,
+ which can be spoiled by 'prepare' of JOIN of other UNION parts
+ if it use same tables
+ */
+ uint tablenr=0;
+ for (TABLE_LIST *table_list= (TABLE_LIST*) sl->table_list.first;
+ table_list;
+ table_list= table_list->next, tablenr++)
{
- thd->lex.current_select= lex_select_save;
- DBUG_RETURN(res);
+ if (table_list->shared)
+ {
+ /*
+ review notes: Check it carefully. I still can't understand
+ why I should not touch table->used_keys. For my point of
+ view we should do here same procedura as it was done by
+ setup_table
+ */
+ DBUG_PRINT("SUBS", ("shared %s", table_list->real_name));
+ TABLE *table= table_list->table;
+ table->used_fields=0;
+ table->const_table=0;
+ table->outer_join=table->null_row=0;
+ table->status=STATUS_NO_RECORD;
+ table->keys_in_use_for_query= table->keys_in_use;
+ table->maybe_null=test(table->outer_join=table_list->outer_join);
+ table->tablenr=tablenr;
+ table->map= (table_map) 1 << tablenr;
+ table->force_index= table_list->force_index;
+ }
}
res= sl->join->optimize();
}
@@ -334,6 +337,7 @@ int st_select_lex_unit::exec()
if (!thd->is_fatal_error) // Check if EOM
{
SELECT_LEX *fake_select = new SELECT_LEX(&thd->lex);
+ fake_select->fake_select= 1;
offset_limit_cnt= (select_cursor->braces ?
global_parameters->offset_limit : 0);
select_limit_cnt= (select_cursor->braces ?