summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/opt_subselect.cc3
-rw-r--r--sql/sql_select.cc23
-rw-r--r--sql/sql_select.h32
3 files changed, 42 insertions, 16 deletions
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index a65f53a86c2..6dcfff4d609 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -4961,7 +4961,8 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
DBUG_ASSERT(!in_to_exists_where || in_to_exists_where->fixed);
DBUG_ASSERT(!in_to_exists_having || in_to_exists_having->fixed);
- Join_plan_state save_qep; /* The original QEP of the subquery. */
+ /* The original QEP of the subquery. */
+ Join_plan_state save_qep(table_count);
/*
Compute and compare the costs of materialization and in-exists if both
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index a526de5a256..9d04204848d 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3046,12 +3046,11 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
key_map const_ref, eq_part;
bool has_expensive_keyparts;
TABLE **table_vector;
- JOIN_TAB *stat,*stat_end,*s,**stat_ref;
+ JOIN_TAB *stat,*stat_end,*s,**stat_ref, **stat_vector;
KEYUSE *keyuse,*start_keyuse;
table_map outer_join=0;
table_map no_rows_const_tables= 0;
SARGABLE_PARAM *sargables= 0;
- JOIN_TAB *stat_vector[MAX_TABLES+1];
List_iterator<TABLE_LIST> ti(tables_list);
TABLE_LIST *tables;
DBUG_ENTER("make_join_statistics");
@@ -3060,9 +3059,19 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
table_count=join->table_count;
stat=(JOIN_TAB*) join->thd->calloc(sizeof(JOIN_TAB)*(table_count));
- stat_ref=(JOIN_TAB**) join->thd->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
+ stat_ref=(JOIN_TAB**) join->thd->alloc(sizeof(JOIN_TAB*)*
+ (MAX_TABLES + table_count + 1));
+ stat_vector= stat_ref + MAX_TABLES;
table_vector=(TABLE**) join->thd->alloc(sizeof(TABLE*)*(table_count*2));
- if (!stat || !stat_ref || !table_vector)
+ join->positions= new (join->thd->mem_root) POSITION[(table_count+1)];
+ /*
+ best_positions is ok to allocate with alloc() as we copy things to it with
+ memcpy()
+ */
+ join->best_positions= (POSITION*) join->thd->alloc(sizeof(POSITION)*
+ (table_count +1));
+
+ if (join->thd->is_fatal_error)
DBUG_RETURN(1); // Eom /* purecov: inspected */
join->best_ref=stat_vector;
@@ -15927,7 +15936,8 @@ join_read_system(JOIN_TAB *tab)
empty_record(table); // Make empty record
return -1;
}
- update_virtual_fields(tab->join->thd, table);
+ if (table->vfield)
+ update_virtual_fields(tab->join->thd, table);
store_record(table,record[1]);
}
else if (!table->status) // Only happens with left join
@@ -15976,7 +15986,8 @@ join_read_const(JOIN_TAB *tab)
return report_error(table, error);
return -1;
}
- update_virtual_fields(tab->join->thd, table);
+ if (table->vfield)
+ update_virtual_fields(tab->join->thd, table);
store_record(table,record[1]);
}
else if (!(table->status & ~STATUS_NULL_ROW)) // Only happens with left join
diff --git a/sql/sql_select.h b/sql/sql_select.h
index a5fa59a070a..a5c0a797ed6 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -742,7 +742,7 @@ public:
Information about a position of table within a join order. Used in join
optimization.
*/
-typedef struct st_position
+typedef struct st_position :public Sql_alloc
{
/* The table that's put into join order */
JOIN_TAB *table;
@@ -844,23 +844,36 @@ protected:
*/
class Join_plan_state {
public:
- DYNAMIC_ARRAY keyuse; /* Copy of the JOIN::keyuse array. */
- POSITION best_positions[MAX_TABLES+1]; /* Copy of JOIN::best_positions */
+ DYNAMIC_ARRAY keyuse; /* Copy of the JOIN::keyuse array. */
+ POSITION *best_positions; /* Copy of JOIN::best_positions */
/* Copies of the JOIN_TAB::keyuse pointers for each JOIN_TAB. */
- KEYUSE *join_tab_keyuse[MAX_TABLES];
+ KEYUSE **join_tab_keyuse;
/* Copies of JOIN_TAB::checked_keys for each JOIN_TAB. */
- key_map join_tab_checked_keys[MAX_TABLES];
- SJ_MATERIALIZATION_INFO *sj_mat_info[MAX_TABLES];
+ key_map *join_tab_checked_keys;
+ SJ_MATERIALIZATION_INFO **sj_mat_info;
+ my_bool error;
public:
- Join_plan_state()
+ Join_plan_state(uint tables) : error(0)
{
keyuse.elements= 0;
keyuse.buffer= NULL;
+ best_positions= 0; /* To detect errors */
+ error= my_multi_malloc(MYF(MY_WME),
+ &best_positions,
+ sizeof(*best_positions) * (tables + 1),
+ &join_tab_keyuse,
+ sizeof(*join_tab_keyuse) * tables,
+ &join_tab_checked_keys,
+ sizeof(*join_tab_checked_keys) * tables,
+ &sj_mat_info,
+ sizeof(sj_mat_info) * tables,
+ NullS) == 0;
}
Join_plan_state(JOIN *join);
~Join_plan_state()
{
delete_dynamic(&keyuse);
+ my_free(best_positions, MYF(0));
}
};
@@ -961,7 +974,7 @@ public:
*/
ha_rows fetch_limit;
/* Finally picked QEP. This is result of join optimization */
- POSITION best_positions[MAX_TABLES+1];
+ POSITION *best_positions;
/******* Join optimization state members start *******/
/*
@@ -971,7 +984,7 @@ public:
TABLE_LIST *emb_sjm_nest;
/* Current join optimization state */
- POSITION positions[MAX_TABLES+1];
+ POSITION *positions;
/*
Bitmap of nested joins embedding the position at the end of the current
@@ -1241,6 +1254,7 @@ public:
exec_const_cond= 0;
group_optimized_away= 0;
no_rows_in_result_called= 0;
+ positions= best_positions= 0;
all_fields= fields_arg;
if (&fields_list != &fields_arg) /* Avoid valgrind-warning */