diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/filesort.cc | 48 | ||||
-rw-r--r-- | sql/sp_head.cc | 17 | ||||
-rw-r--r-- | sql/sp_head.h | 12 | ||||
-rw-r--r-- | sql/sql_class.cc | 4 | ||||
-rw-r--r-- | sql/sql_select.cc | 12 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 12 | ||||
-rw-r--r-- | sql/table.h | 1 |
7 files changed, 77 insertions, 29 deletions
diff --git a/sql/filesort.cc b/sql/filesort.cc index 9e82ef2acbe..e6842cec4a2 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -41,8 +41,9 @@ if (my_b_write((file),(uchar*) (from),param->ref_length)) \ /* functions defined in this file */ -static char **make_char_array(char **old_pos, register uint fields, - uint length, myf my_flag); +static size_t char_array_size(uint fields, uint length); +static uchar **make_char_array(uchar **old_pos, uint fields, + uint length, myf my_flag); static uchar *read_buffpek_from_file(IO_CACHE *buffer_file, uint count, uchar *buf); static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select, @@ -221,10 +222,22 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, ulong old_memavl; ulong keys= memavl/(param.rec_length+sizeof(char*)); param.keys=(uint) min(records+1, keys); + + if (table_sort.sort_keys && + table_sort.sort_keys_size != char_array_size(param.keys, + param.rec_length)) + { + x_free((uchar*) table_sort.sort_keys); + table_sort.sort_keys= NULL; + table_sort.sort_keys_size= 0; + } if ((table_sort.sort_keys= - (uchar **) make_char_array((char **) table_sort.sort_keys, - param.keys, param.rec_length, MYF(0)))) + make_char_array(table_sort.sort_keys, + param.keys, param.rec_length, MYF(0)))) + { + table_sort.sort_keys_size= char_array_size(param.keys, param.rec_length); break; + } old_memavl=memavl; if ((memavl=memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory) memavl= min_sort_memory; @@ -306,6 +319,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, { x_free((uchar*) sort_keys); table_sort.sort_keys= 0; + table_sort.sort_keys_size= 0; x_free((uchar*) buffpek); table_sort.buffpek= 0; table_sort.buffpek_len= 0; @@ -353,6 +367,7 @@ void filesort_free_buffers(TABLE *table, bool full) { x_free((uchar*) table->sort.sort_keys); table->sort.sort_keys= 0; + table->sort.sort_keys_size= 0; } if (table->sort.buffpek) { @@ -372,19 +387,28 @@ void filesort_free_buffers(TABLE *table, bool full) /** Make a array of string pointers. */ -static char **make_char_array(char **old_pos, register uint fields, - uint length, myf my_flag) +static size_t char_array_size(uint fields, uint length) { - register char **pos; - char *char_pos; + return fields * (length + sizeof(uchar*)); +} + + +static uchar **make_char_array(uchar **old_pos, uint fields, + uint length, myf my_flag) +{ + register uchar **pos; + uchar *char_pos; DBUG_ENTER("make_char_array"); if (old_pos || - (old_pos= (char**) my_malloc((uint) fields*(length+sizeof(char*)), - my_flag))) + (old_pos= (uchar**) my_malloc(char_array_size(fields, length), my_flag))) { - pos=old_pos; char_pos=((char*) (pos+fields)) -length; - while (fields--) *(pos++) = (char_pos+= length); + pos=old_pos; + char_pos= ((uchar*)(pos+fields)) -length; + while (fields--) + { + *(pos++) = (char_pos+= length); + } } DBUG_RETURN(old_pos); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index db9142e47f5..7eef9f5ab28 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -3356,6 +3356,23 @@ sp_instr_hpush_jump::opt_mark(sp_head *sp, List<sp_instr> *leads) m_optdest= sp->get_instr(m_dest); } sp->add_mark_lead(m_dest, leads); + + /* + For continue handlers, all instructions in the scope of the handler + are possible leads. For example, the instruction after freturn might + be executed if the freturn triggers the condition handled by the + continue handler. + + m_dest marks the start of the handler scope. It's added as a lead + above, so we start on m_dest+1 here. + m_opt_hpop is the hpop marking the end of the handler scope. + */ + if (m_type == SP_HANDLER_CONTINUE) + { + for (uint scope_ip= m_dest+1; scope_ip <= m_opt_hpop; scope_ip++) + sp->add_mark_lead(scope_ip, leads); + } + return m_ip+1; } diff --git a/sql/sp_head.h b/sql/sp_head.h index da490527f42..a026ac47221 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -1000,7 +1000,7 @@ class sp_instr_hpush_jump : public sp_instr_jump public: sp_instr_hpush_jump(uint ip, sp_pcontext *ctx, int htype, uint fp) - : sp_instr_jump(ip, ctx), m_type(htype), m_frame(fp) + : sp_instr_jump(ip, ctx), m_type(htype), m_frame(fp), m_opt_hpop(0) { m_cond.empty(); } @@ -1022,6 +1022,15 @@ public: return m_ip; } + virtual void backpatch(uint dest, sp_pcontext *dst_ctx) + { + DBUG_ASSERT(!m_dest || !m_opt_hpop); + if (!m_dest) + m_dest= dest; + else + m_opt_hpop= dest; + } + inline void add_condition(struct sp_cond_type *cond) { m_cond.push_front(cond); @@ -1031,6 +1040,7 @@ private: int m_type; ///< Handler type uint m_frame; + uint m_opt_hpop; // hpop marking end of handler scope. List<struct sp_cond_type> m_cond; }; // class sp_instr_hpush_jump : public sp_instr_jump diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 7fb1d2ade5f..32e2e90acd7 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -122,9 +122,9 @@ Key::Key(const Key &rhs, MEM_ROOT *mem_root) */ Foreign_key::Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root) - :Key(rhs), + :Key(rhs,mem_root), ref_table(rhs.ref_table), - ref_columns(rhs.ref_columns), + ref_columns(rhs.ref_columns,mem_root), delete_opt(rhs.delete_opt), update_opt(rhs.update_opt), match_opt(rhs.match_opt) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 72c826ff32d..5f1efabfc97 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8947,11 +8947,9 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top) } /* Flatten nested joins that can be flattened. */ - TABLE_LIST *right_neighbor= NULL; li.rewind(); while ((table= li++)) { - bool fix_name_res= FALSE; nested_join= table->nested_join; if (nested_join && !table->on_expr) { @@ -8963,15 +8961,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top) tbl->join_list= table->join_list; } li.replace(nested_join->join_list); - /* Need to update the name resolution table chain when flattening joins */ - fix_name_res= TRUE; - table= *li.ref(); - } - if (fix_name_res) - table->next_name_resolution_table= right_neighbor ? - right_neighbor->first_leaf_for_name_resolution() : - NULL; - right_neighbor= table; + } } DBUG_RETURN(conds); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index facbc6d3e95..7e7ff7e91ca 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2532,9 +2532,15 @@ sp_decl: sp_instr_hpush_jump *i= new sp_instr_hpush_jump(sp->instructions(), ctx, $2, ctx->current_var_count()); - if (i == NULL || - sp->add_instr(i) || - sp->push_backpatch(i, ctx->push_label((char *)"", 0))) + if (i == NULL || sp->add_instr(i)) + MYSQL_YYABORT; + + /* For continue handlers, mark end of handler scope. */ + if ($2 == SP_HANDLER_CONTINUE && + sp->push_backpatch(i, ctx->last_label())) + MYSQL_YYABORT; + + if (sp->push_backpatch(i, ctx->push_label(empty_c_string, 0))) MYSQL_YYABORT; } sp_hcond_list sp_proc_stmt diff --git a/sql/table.h b/sql/table.h index 20f11f4e7e1..690abdff714 100644 --- a/sql/table.h +++ b/sql/table.h @@ -157,6 +157,7 @@ typedef struct st_filesort_info { IO_CACHE *io_cache; /* If sorted through filesort */ uchar **sort_keys; /* Buffer for sorting keys */ + size_t sort_keys_size; /* Number of bytes allocated */ uchar *buffpek; /* Buffer for buffpek structures */ uint buffpek_len; /* Max number of buffpeks in the buffer */ uchar *addon_buf; /* Pointer to a buffer if sorted with fields */ |