summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc44
1 files changed, 38 insertions, 6 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 2e966dbdde3..d7f92392c5e 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1128,6 +1128,30 @@ JOIN::optimize()
{
conds=new Item_int((longlong) 0,1); // Always false
}
+
+ /*
+ It's necessary to check const part of HAVING cond as there is a
+ chance that some cond parts may become const items after
+ make_join_statistics() (for example when Item is a reference to
+ cost table field from outer join).
+
+ This check is performed only for those conditions which do not use
+ aggregate functions. In such case temporary table may not be used
+ and const condition elements may be lost during further having
+ condition transformation in JOIN::exec.
+ */
+ if (having && const_table_map && !having->with_sum_func)
+ {
+ having->update_used_tables();
+ having= remove_eq_conds(thd, having, &having_value);
+ if (having_value == Item::COND_FALSE)
+ {
+ having= new Item_int((longlong) 0,1);
+ zero_result_cause= "Impossible HAVING noticed after reading const tables";
+ DBUG_RETURN(0);
+ }
+ }
+
if (make_join_select(this, select, conds))
{
zero_result_cause=
@@ -11888,6 +11912,7 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
enum_nested_loop_state rc= NESTED_LOOP_OK;
int error;
READ_RECORD *info;
+ SQL_SELECT *select;
join_tab->table->null_row= 0;
if (!join_tab->cache.records)
@@ -11902,7 +11927,7 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
join_tab->select->quick=0;
}
}
- /* read through all records */
+ /* read through all records */
if ((error=join_init_read_record(join_tab)))
{
reset_cache_write(&join_tab->cache);
@@ -11916,15 +11941,16 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
}
info= &join_tab->read_record;
+ select= join_tab->select;
+
do
{
+ int err= 0;
if (join->thd->killed)
{
join->thd->send_kill_message();
return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
}
- int err= 0;
- SQL_SELECT *select=join_tab->select;
if (rc == NESTED_LOOP_OK)
update_virtual_fields(join->thd, join_tab->table);
if (rc == NESTED_LOOP_OK &&
@@ -11932,8 +11958,11 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
(err= join_tab->cache.select->skip_record(join->thd)) != 0 ))
{
if (err < 0)
+ {
+ reset_cache_write(&join_tab->cache);
return NESTED_LOOP_ERROR;
- rc= NESTED_LOOP_OK;
+ }
+
reset_cache_read(&join_tab->cache);
for (uint i= (join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
{
@@ -11942,7 +11971,10 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
if (!select || (err= select->skip_record(join->thd)) != 0)
{
if (err < 0)
+ {
+ reset_cache_write(&join_tab->cache);
return NESTED_LOOP_ERROR;
+ }
rc= (join_tab->next_select)(join,join_tab+1,0);
if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
{
@@ -16695,7 +16727,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
the UNION to provide precise EXPLAIN information will hardly be
appreciated :)
*/
- char table_name_buffer[NAME_LEN];
+ char table_name_buffer[SAFE_NAME_LEN];
item_list.empty();
/* id */
item_list.push_back(new Item_null);
@@ -16768,7 +16800,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
char buff1[512], buff2[512], buff3[512];
char keylen_str_buf[64];
String extra(buff, sizeof(buff),cs);
- char table_name_buffer[NAME_LEN];
+ char table_name_buffer[SAFE_NAME_LEN];
String tmp1(buff1,sizeof(buff1),cs);
String tmp2(buff2,sizeof(buff2),cs);
String tmp3(buff3,sizeof(buff3),cs);