summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/filesort.cc48
-rw-r--r--sql/sp_head.cc17
-rw-r--r--sql/sp_head.h12
-rw-r--r--sql/sql_class.cc4
-rw-r--r--sql/sql_select.cc12
-rw-r--r--sql/sql_yacc.yy12
-rw-r--r--sql/table.h1
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 */