Commit dfcc502a authored by unknown's avatar unknown

Finished merging wl5986 started by Igor.

parent 2534521f
...@@ -2501,12 +2501,12 @@ my_xpath_parse_VariableReference(MY_XPATH *xpath) ...@@ -2501,12 +2501,12 @@ my_xpath_parse_VariableReference(MY_XPATH *xpath)
xpath->item= new Item_func_get_user_var(name); xpath->item= new Item_func_get_user_var(name);
else else
{ {
sp_variable_t *spv; sp_variable *spv;
sp_pcontext *spc; sp_pcontext *spc;
LEX *lex; LEX *lex;
if ((lex= current_thd->lex) && if ((lex= current_thd->lex) &&
(spc= lex->spcont) && (spc= lex->spcont) &&
(spv= spc->find_variable(&name))) (spv= spc->find_variable(name, false)))
{ {
Item_splocal *splocal= new Item_splocal(name, spv->offset, spv->type, 0); Item_splocal *splocal= new Item_splocal(name, spv->offset, spv->type, 0);
#ifndef DBUG_OFF #ifndef DBUG_OFF
......
...@@ -5060,7 +5060,7 @@ public: ...@@ -5060,7 +5060,7 @@ public:
select_value_catcher(Item_subselect *item_arg) select_value_catcher(Item_subselect *item_arg)
:select_subselect(item_arg) :select_subselect(item_arg)
{} {}
int send_data(List<Item> &items); bool send_data(List<Item> &items);
int setup(List<Item> *items); int setup(List<Item> *items);
bool assigned; /* TRUE <=> we've caught a value */ bool assigned; /* TRUE <=> we've caught a value */
uint n_elements; /* How many elements we get */ uint n_elements; /* How many elements we get */
...@@ -5088,7 +5088,7 @@ int select_value_catcher::setup(List<Item> *items) ...@@ -5088,7 +5088,7 @@ int select_value_catcher::setup(List<Item> *items)
} }
int select_value_catcher::send_data(List<Item> &items) bool select_value_catcher::send_data(List<Item> &items)
{ {
DBUG_ENTER("select_value_catcher::send_data"); DBUG_ENTER("select_value_catcher::send_data");
DBUG_ASSERT(!assigned); DBUG_ASSERT(!assigned);
......
This diff is collapsed.
...@@ -30,8 +30,9 @@ ...@@ -30,8 +30,9 @@
#include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */ #include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */
#include "sql_class.h" // THD, set_var.h: THD #include "sql_class.h" // THD, set_var.h: THD
#include "set_var.h" // Item #include "set_var.h" // Item
#include "sp.h" #include "sp_pcontext.h" // sp_pcontext
#include <stddef.h> #include <stddef.h>
#include "sp.h"
/** /**
@defgroup Stored_Routines Stored Routines @defgroup Stored_Routines Stored Routines
...@@ -39,6 +40,11 @@ ...@@ -39,6 +40,11 @@
@{ @{
*/ */
// Values for the type enum. This reflects the order of the enum declaration
// in the CREATE TABLE command.
//#define TYPE_ENUM_FUNCTION 1 #define TYPE_ENUM_PROCEDURE 2 #define
//TYPE_ENUM_TRIGGER 3 #define TYPE_ENUM_PROXY 4
Item_result Item_result
sp_map_result_type(enum enum_field_types type); sp_map_result_type(enum enum_field_types type);
...@@ -48,12 +54,9 @@ sp_map_item_type(enum enum_field_types type); ...@@ -48,12 +54,9 @@ sp_map_item_type(enum enum_field_types type);
uint uint
sp_get_flags_for_command(LEX *lex); sp_get_flags_for_command(LEX *lex);
struct sp_label;
class sp_instr; class sp_instr;
class sp_instr_opt_meta; class sp_instr_opt_meta;
class sp_instr_jump_if_not; class sp_instr_jump_if_not;
struct sp_cond_type;
struct sp_variable;
/*************************************************************************/ /*************************************************************************/
...@@ -602,7 +605,7 @@ public: ...@@ -602,7 +605,7 @@ public:
Get the continuation destination of this instruction. Get the continuation destination of this instruction.
@return the continuation destination @return the continuation destination
*/ */
virtual uint get_cont_dest(); virtual uint get_cont_dest() const;
/* /*
Execute core function of instruction after all preparations (e.g. Execute core function of instruction after all preparations (e.g.
...@@ -874,7 +877,7 @@ public: ...@@ -874,7 +877,7 @@ public:
virtual void set_destination(uint old_dest, uint new_dest) virtual void set_destination(uint old_dest, uint new_dest)
= 0; = 0;
virtual uint get_cont_dest(); virtual uint get_cont_dest() const;
protected: protected:
...@@ -1025,15 +1028,21 @@ class sp_instr_hpush_jump : public sp_instr_jump ...@@ -1025,15 +1028,21 @@ class sp_instr_hpush_jump : public sp_instr_jump
public: public:
sp_instr_hpush_jump(uint ip, sp_pcontext *ctx, int htype, uint fp) sp_instr_hpush_jump(uint ip,
: sp_instr_jump(ip, ctx), m_type(htype), m_frame(fp), m_opt_hpop(0) sp_pcontext *ctx,
sp_handler *handler)
:sp_instr_jump(ip, ctx),
m_handler(handler),
m_opt_hpop(0),
m_frame(ctx->current_var_count())
{ {
m_cond.empty(); DBUG_ASSERT(m_handler->condition_values.elements == 0);
} }
virtual ~sp_instr_hpush_jump() virtual ~sp_instr_hpush_jump()
{ {
m_cond.empty(); m_handler->condition_values.empty();
m_handler= NULL;
} }
virtual int execute(THD *thd, uint *nextp); virtual int execute(THD *thd, uint *nextp);
...@@ -1057,17 +1066,24 @@ public: ...@@ -1057,17 +1066,24 @@ public:
m_opt_hpop= dest; m_opt_hpop= dest;
} }
inline void add_condition(struct sp_cond_type *cond) void add_condition(sp_condition_value *condition_value)
{ { m_handler->condition_values.push_back(condition_value); }
m_cond.push_front(cond);
} sp_handler *get_handler()
{ return m_handler; }
private:
private: private:
/// Handler.
sp_handler *m_handler;
/// hpop marking end of handler scope.
uint m_opt_hpop;
int m_type; ///< Handler type // This attribute is needed for SHOW PROCEDURE CODE only (i.e. it's needed in
// debug version only). It's used in print().
uint m_frame; 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 }; // class sp_instr_hpush_jump : public sp_instr_jump
...@@ -1104,8 +1120,9 @@ class sp_instr_hreturn : public sp_instr_jump ...@@ -1104,8 +1120,9 @@ class sp_instr_hreturn : public sp_instr_jump
public: public:
sp_instr_hreturn(uint ip, sp_pcontext *ctx, uint fp) sp_instr_hreturn(uint ip, sp_pcontext *ctx)
: sp_instr_jump(ip, ctx), m_frame(fp) :sp_instr_jump(ip, ctx),
m_frame(ctx->current_var_count())
{} {}
virtual ~sp_instr_hreturn() virtual ~sp_instr_hreturn()
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -99,29 +99,65 @@ template <class Elem> class Dynamic_array ...@@ -99,29 +99,65 @@ template <class Elem> class Dynamic_array
DYNAMIC_ARRAY array; DYNAMIC_ARRAY array;
public: public:
Dynamic_array(uint prealloc=16, uint increment=16) Dynamic_array(uint prealloc=16, uint increment=16)
{
init(prealloc, increment);
}
void init(uint prealloc=16, uint increment=16)
{ {
my_init_dynamic_array(&array, sizeof(Elem), prealloc, increment, my_init_dynamic_array(&array, sizeof(Elem), prealloc, increment,
MYF(MY_THREAD_SPECIFIC)); MYF(MY_THREAD_SPECIFIC));
} }
/**
@note Though formally this could be declared "const" it would be
misleading at it returns a non-const pointer to array's data.
*/
Elem& at(int idx) Elem& at(int idx)
{ {
return *(((Elem*)array.buffer) + idx); return *(((Elem*)array.buffer) + idx);
} }
/// Const variant of at(), which cannot change data
const Elem& at(int idx) const
{
return *(((Elem*)array.buffer) + idx);
}
/// @returns pointer to first element; undefined behaviour if array is empty
Elem *front() Elem *front()
{ {
DBUG_ASSERT(array.elements >= 1);
return (Elem*)array.buffer; return (Elem*)array.buffer;
} }
/// @returns pointer to first element; undefined behaviour if array is empty
const Elem *front() const
{
DBUG_ASSERT(array.elements >= 1);
return (const Elem*)array.buffer;
}
/// @returns pointer to last element; undefined behaviour if array is empty.
Elem *back() Elem *back()
{ {
return ((Elem*)array.buffer) + array.elements; DBUG_ASSERT(array.elements >= 1);
return ((Elem*)array.buffer) + (array.elements - 1);
}
/// @returns pointer to last element; undefined behaviour if array is empty.
const Elem *back() const
{
DBUG_ASSERT(array.elements >= 1);
return ((const Elem*)array.buffer) + (array.elements - 1);
} }
bool append(Elem &el) /**
@retval false ok
@retval true OOM, @c my_error() has been called.
*/
bool append(const Elem &el)
{ {
return (insert_dynamic(&array, (uchar*)&el)); return insert_dynamic(&array, &el);
} }
/// Pops the last element. Does nothing if array is empty. /// Pops the last element. Does nothing if array is empty.
...@@ -135,91 +171,37 @@ public: ...@@ -135,91 +171,37 @@ public:
delete_dynamic_element(&array, idx); delete_dynamic_element(&array, idx);
} }
int elements() int elements() const
{ {
return array.elements; return array.elements;
} }
~Dynamic_array() void elements(uint num_elements)
{
delete_dynamic(&array);
}
typedef int (*CMP_FUNC)(const Elem *el1, const Elem *el2);
void sort(CMP_FUNC cmp_func)
{
my_qsort(array.buffer, array.elements, sizeof(Elem), (qsort_cmp)cmp_func);
}
};
/*
Array of pointers to Elem that uses memory from MEM_ROOT
MEM_ROOT has no realloc() so this is supposed to be used for cases when
reallocations are rare.
*/
template <class Elem> class Array
{
enum {alloc_increment = 16};
Elem **buffer;
uint n_elements, max_element;
public:
Array(MEM_ROOT *mem_root, uint prealloc=16)
{
buffer= (Elem**)alloc_root(mem_root, prealloc * sizeof(Elem**));
max_element = buffer? prealloc : 0;
n_elements= 0;
}
Elem& at(int idx)
{
return *(((Elem*)buffer) + idx);
}
Elem **front()
{
return buffer;
}
Elem **back()
{ {
return buffer + n_elements; DBUG_ASSERT(num_elements <= array.max_element);
array.elements= num_elements;
} }
bool append(MEM_ROOT *mem_root, Elem *el) void clear()
{ {
if (n_elements == max_element) elements(0);
{
Elem **newbuf;
if (!(newbuf= (Elem**)alloc_root(mem_root, (n_elements + alloc_increment)*
sizeof(Elem**))))
{
return FALSE;
}
memcpy(newbuf, buffer, n_elements*sizeof(Elem*));
buffer= newbuf;
}
buffer[n_elements++]= el;
return FALSE;
} }
int elements() void set(uint idx, const Elem &el)
{ {
return n_elements; set_dynamic(&array, &el, idx);
} }
void clear() ~Dynamic_array()
{ {
n_elements= 0; delete_dynamic(&array);
} }
typedef int (*CMP_FUNC)(Elem * const *el1, Elem *const *el2); typedef int (*CMP_FUNC)(const Elem *el1, const Elem *el2);
void sort(CMP_FUNC cmp_func) void sort(CMP_FUNC cmp_func)
{ {
my_qsort(buffer, n_elements, sizeof(Elem*), (qsort_cmp)cmp_func); my_qsort(array.buffer, array.elements, sizeof(Elem), (qsort_cmp)cmp_func);
} }
}; };
......
...@@ -72,6 +72,8 @@ ...@@ -72,6 +72,8 @@
char internal_table_name[2]= "*"; char internal_table_name[2]= "*";
char empty_c_string[1]= {0}; /* used for not defined db */ char empty_c_string[1]= {0}; /* used for not defined db */
LEX_STRING EMPTY_STR= { (char *) "", 0 };
const char * const THD::DEFAULT_WHERE= "field list"; const char * const THD::DEFAULT_WHERE= "field list";
/**************************************************************************** /****************************************************************************
...@@ -2454,7 +2456,7 @@ void select_send::cleanup() ...@@ -2454,7 +2456,7 @@ void select_send::cleanup()
/* Send data to client. Returns 0 if ok */ /* Send data to client. Returns 0 if ok */
int select_send::send_data(List<Item> &items) bool select_send::send_data(List<Item> &items)
{ {
Protocol *protocol= thd->protocol; Protocol *protocol= thd->protocol;
DBUG_ENTER("select_send::send_data"); DBUG_ENTER("select_send::send_data");
...@@ -2744,7 +2746,7 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u) ...@@ -2744,7 +2746,7 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
(int) (uchar) (x) == line_sep_char || \ (int) (uchar) (x) == line_sep_char || \
!(x)) !(x))
int select_export::send_data(List<Item> &items) bool select_export::send_data(List<Item> &items)
{ {
DBUG_ENTER("select_export::send_data"); DBUG_ENTER("select_export::send_data");
...@@ -3003,7 +3005,7 @@ select_dump::prepare(List<Item> &list __attribute__((unused)), ...@@ -3003,7 +3005,7 @@ select_dump::prepare(List<Item> &list __attribute__((unused)),
} }
int select_dump::send_data(List<Item> &items) bool select_dump::send_data(List<Item> &items)
{ {
List_iterator_fast<Item> li(items); List_iterator_fast<Item> li(items);
char buff[MAX_FIELD_WIDTH]; char buff[MAX_FIELD_WIDTH];
...@@ -3051,7 +3053,7 @@ select_subselect::select_subselect(Item_subselect *item_arg) ...@@ -3051,7 +3053,7 @@ select_subselect::select_subselect(Item_subselect *item_arg)
} }
int select_singlerow_subselect::send_data(List<Item> &items) bool select_singlerow_subselect::send_data(List<Item> &items)
{ {
DBUG_ENTER("select_singlerow_subselect::send_data"); DBUG_ENTER("select_singlerow_subselect::send_data");
Item_singlerow_subselect *it= (Item_singlerow_subselect *)item; Item_singlerow_subselect *it= (Item_singlerow_subselect *)item;
...@@ -3085,7 +3087,7 @@ void select_max_min_finder_subselect::cleanup() ...@@ -3085,7 +3087,7 @@ void select_max_min_finder_subselect::cleanup()
} }
int select_max_min_finder_subselect::send_data(List<Item> &items) bool select_max_min_finder_subselect::send_data(List<Item> &items)
{ {
DBUG_ENTER("select_max_min_finder_subselect::send_data"); DBUG_ENTER("select_max_min_finder_subselect::send_data");
Item_maxmin_subselect *it= (Item_maxmin_subselect *)item; Item_maxmin_subselect *it= (Item_maxmin_subselect *)item;
...@@ -3202,7 +3204,7 @@ bool select_max_min_finder_subselect::cmp_str() ...@@ -3202,7 +3204,7 @@ bool select_max_min_finder_subselect::cmp_str()
return (sortcmp(val1, val2, cache->collation.collation) < 0); return (sortcmp(val1, val2, cache->collation.collation) < 0);
} }
int select_exists_subselect::send_data(List<Item> &items) bool select_exists_subselect::send_data(List<Item> &items)
{ {
DBUG_ENTER("select_exists_subselect::send_data"); DBUG_ENTER("select_exists_subselect::send_data");
Item_exists_subselect *it= (Item_exists_subselect *)item; Item_exists_subselect *it= (Item_exists_subselect *)item;
...@@ -3585,7 +3587,7 @@ Statement_map::~Statement_map() ...@@ -3585,7 +3587,7 @@ Statement_map::~Statement_map()
my_hash_free(&st_hash); my_hash_free(&st_hash);
} }
int select_dumpvar::send_data(List<Item> &items) bool select_dumpvar::send_data(List<Item> &items)
{ {
List_iterator_fast<my_var> var_li(var_list); List_iterator_fast<my_var> var_li(var_list);
List_iterator<Item> it(items); List_iterator<Item> it(items);
...@@ -3691,7 +3693,7 @@ void select_materialize_with_stats::cleanup() ...@@ -3691,7 +3693,7 @@ void select_materialize_with_stats::cleanup()
@return FALSE on success @return FALSE on success
*/ */
int select_materialize_with_stats::send_data(List<Item> &items) bool select_materialize_with_stats::send_data(List<Item> &items)
{ {
List_iterator_fast<Item> item_it(items); List_iterator_fast<Item> item_it(items);
Item *cur_item; Item *cur_item;
......
...@@ -121,6 +121,7 @@ enum enum_filetype { FILETYPE_CSV, FILETYPE_XML }; ...@@ -121,6 +121,7 @@ enum enum_filetype { FILETYPE_CSV, FILETYPE_XML };
extern char internal_table_name[2]; extern char internal_table_name[2];
extern char empty_c_string[1]; extern char empty_c_string[1];
extern LEX_STRING EMPTY_STR;
extern MYSQL_PLUGIN_IMPORT const char **errmesg; extern MYSQL_PLUGIN_IMPORT const char **errmesg;
extern bool volatile shutdown_in_progress; extern bool volatile shutdown_in_progress;
...@@ -3465,7 +3466,7 @@ public: ...@@ -3465,7 +3466,7 @@ public:
send_data returns 0 on ok, 1 on error and -1 if data was ignored, for send_data returns 0 on ok, 1 on error and -1 if data was ignored, for
example for a duplicate row entry written to a temp table. example for a duplicate row entry written to a temp table.
*/ */
virtual int send_data(List<Item> &items)=0; virtual bool send_data(List<Item> &items)=0;
virtual ~select_result_sink() {}; virtual ~select_result_sink() {};
}; };
...@@ -3557,7 +3558,7 @@ public: ...@@ -3557,7 +3558,7 @@ public:
TABLE *dst_table; /* table to write into */ TABLE *dst_table; /* table to write into */
/* The following is called in the child thread: */ /* The following is called in the child thread: */
int send_data(List<Item> &items); bool send_data(List<Item> &items);
}; };
...@@ -3592,7 +3593,7 @@ class select_send :public select_result { ...@@ -3592,7 +3593,7 @@ class select_send :public select_result {
public: public:
select_send() :is_result_set_started(FALSE) {} select_send() :is_result_set_started(FALSE) {}
bool send_result_set_metadata(List<Item> &list, uint flags); bool send_result_set_metadata(List<Item> &list, uint flags);
int send_data(List<Item> &items); bool send_data(List<Item> &items);
bool send_eof(); bool send_eof();
virtual bool check_simple_select() const { return FALSE; } virtual bool check_simple_select() const { return FALSE; }
void abort_result_set(); void abort_result_set();
...@@ -3655,7 +3656,7 @@ public: ...@@ -3655,7 +3656,7 @@ public:
select_export(sql_exchange *ex) :select_to_file(ex) {} select_export(sql_exchange *ex) :select_to_file(ex) {}
~select_export(); ~select_export();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
int send_data(List<Item> &items); bool send_data(List<Item> &items);
}; };
...@@ -3663,7 +3664,7 @@ class select_dump :public select_to_file { ...@@ -3663,7 +3664,7 @@ class select_dump :public select_to_file {
public: public:
select_dump(sql_exchange *ex) :select_to_file(ex) {} select_dump(sql_exchange *ex) :select_to_file(ex) {}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
int send_data(List<Item> &items); bool send_data(List<Item> &items);
}; };
...@@ -3682,7 +3683,7 @@ class select_insert :public select_result_interceptor { ...@@ -3682,7 +3683,7 @@ class select_insert :public select_result_interceptor {
~select_insert(); ~select_insert();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
virtual int prepare2(void); virtual int prepare2(void);
virtual int send_data(List<Item> &items); virtual bool send_data(List<Item> &items);
virtual void store_values(List<Item> &values); virtual void store_values(List<Item> &values);
virtual bool can_rollback_data() { return 0; } virtual bool can_rollback_data() { return 0; }
void send_error(uint errcode,const char *err); void send_error(uint errcode,const char *err);
...@@ -3865,7 +3866,7 @@ public: ...@@ -3865,7 +3866,7 @@ public:
select_union() :write_err(0), table(0), records(0) { tmp_table_param.init(); } select_union() :write_err(0), table(0), records(0) { tmp_table_param.init(); }
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
int send_data(List<Item> &items); bool send_data(List<Item> &items);
bool send_eof(); bool send_eof();
bool flush(); bool flush();
void cleanup(); void cleanup();
...@@ -3884,7 +3885,7 @@ protected: ...@@ -3884,7 +3885,7 @@ protected:
Item_subselect *item; Item_subselect *item;
public: public:
select_subselect(Item_subselect *item); select_subselect(Item_subselect *item);
int send_data(List<Item> &items)=0; bool send_data(List<Item> &items)=0;
bool send_eof() { return 0; }; bool send_eof() { return 0; };
}; };
...@@ -3895,7 +3896,7 @@ public: ...@@ -3895,7 +3896,7 @@ public:
select_singlerow_subselect(Item_subselect *item_arg) select_singlerow_subselect(Item_subselect *item_arg)
:select_subselect(item_arg) :select_subselect(item_arg)
{} {}
int send_data(List<Item> &items); bool send_data(List<Item> &items);
}; };
...@@ -3945,7 +3946,7 @@ public: ...@@ -3945,7 +3946,7 @@ public:
bool bit_fields_as_long, bool bit_fields_as_long,
bool create_table); bool create_table);
bool init_result_table(ulonglong select_options); bool init_result_table(ulonglong select_options);
int send_data(List<Item> &items); bool send_data(List<Item> &items);
void cleanup(); void cleanup();
ha_rows get_null_count_of_col(uint idx) ha_rows get_null_count_of_col(uint idx)
{ {
...@@ -3979,7 +3980,7 @@ public: ...@@ -3979,7 +3980,7 @@ public:
:select_subselect(item_arg), cache(0), fmax(mx), is_all(all) :select_subselect(item_arg), cache(0), fmax(mx), is_all(all)
{} {}
void cleanup(); void cleanup();
int send_data(List<Item> &items); bool send_data(List<Item> &items);
bool cmp_real(); bool cmp_real();
bool cmp_int(); bool cmp_int();
bool cmp_decimal(); bool cmp_decimal();
...@@ -3992,7 +3993,7 @@ class select_exists_subselect :public select_subselect ...@@ -3992,7 +3993,7 @@ class select_exists_subselect :public select_subselect
public: public:
select_exists_subselect(Item_subselect *item_arg) select_exists_subselect(Item_subselect *item_arg)
:select_subselect(item_arg){} :select_subselect(item_arg){}
int send_data(List<Item> &items); bool send_data(List<Item> &items);
}; };
...@@ -4244,7 +4245,7 @@ public: ...@@ -4244,7 +4245,7 @@ public:
multi_delete(TABLE_LIST *dt, uint num_of_tables); multi_delete(TABLE_LIST *dt, uint num_of_tables);
~multi_delete(); ~multi_delete();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
int send_data(List<Item> &items); bool send_data(List<Item> &items);
bool initialize_tables (JOIN *join); bool initialize_tables (JOIN *join);
void send_error(uint errcode,const char *err); void send_error(uint errcode,const char *err);
int do_deletes(); int do_deletes();
...@@ -4292,7 +4293,7 @@ public: ...@@ -4292,7 +4293,7 @@ public:
enum_duplicates handle_duplicates, bool ignore); enum_duplicates handle_duplicates, bool ignore);
~multi_update(); ~multi_update();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
int send_data(List<Item> &items); bool send_data(List<Item> &items);
bool initialize_tables (JOIN *join); bool initialize_tables (JOIN *join);
void send_error(uint errcode,const char *err); void send_error(uint errcode,const char *err);
int do_updates(); int do_updates();
...@@ -4335,7 +4336,7 @@ public: ...@@ -4335,7 +4336,7 @@ public:
select_dumpvar() { var_list.empty(); row_count= 0;} select_dumpvar() { var_list.empty(); row_count= 0;}
~select_dumpvar() {} ~select_dumpvar() {}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
int send_data(List<Item> &items); bool send_data(List<Item> &items);
bool send_eof(); bool send_eof();
virtual bool check_simple_select() const; virtual bool check_simple_select() const;
void cleanup(); void cleanup();
......
...@@ -759,7 +759,7 @@ multi_delete::~multi_delete() ...@@ -759,7 +759,7 @@ multi_delete::~multi_delete()
} }
int multi_delete::send_data(List<Item> &values) bool multi_delete::send_data(List<Item> &values)
{ {
int secure_counter= delete_while_scanning ? -1 : 0; int secure_counter= delete_while_scanning ? -1 : 0;
TABLE_LIST *del_table; TABLE_LIST *del_table;
......
...@@ -1001,3 +1001,32 @@ uint32 convert_error_message(char *to, uint32 to_length, CHARSET_INFO *to_cs, ...@@ -1001,3 +1001,32 @@ uint32 convert_error_message(char *to, uint32 to_length, CHARSET_INFO *to_cs,
*errors= error_count; *errors= error_count;
return (uint32) (to - to_start); return (uint32) (to - to_start);
} }
/**
Sanity check for SQLSTATEs. The function does not check if it's really an
existing SQL-state (there are just too many), it just checks string length and
looks for bad characters.
@param sqlstate the condition SQLSTATE.
@retval true if it's ok.
@retval false if it's bad.
*/
bool is_sqlstate_valid(const LEX_STRING *sqlstate)
{
if (sqlstate->length != 5)
return false;
for (int i= 0 ; i < 5 ; ++i)
{
char c = sqlstate->str[i];
if ((c < '0' || '9' < c) &&
(c < 'A' || 'Z' < c))
return false;
}
return true;
}
...@@ -3537,7 +3537,7 @@ select_insert::~select_insert() ...@@ -3537,7 +3537,7 @@ select_insert::~select_insert()
} }
int select_insert::send_data(List<Item> &values) bool select_insert::send_data(List<Item> &values)
{ {
DBUG_ENTER("select_insert::send_data"); DBUG_ENTER("select_insert::send_data");
bool error=0; bool error=0;
......
...@@ -126,7 +126,7 @@ class Select_fetch_protocol_binary: public select_send ...@@ -126,7 +126,7 @@ class Select_fetch_protocol_binary: public select_send
public: public:
Select_fetch_protocol_binary(THD *thd); Select_fetch_protocol_binary(THD *thd);
virtual bool send_result_set_metadata(List<Item> &list, uint flags); virtual bool send_result_set_metadata(List<Item> &list, uint flags);
virtual int send_data(List<Item> &items); virtual bool send_data(List<Item> &items);
virtual bool send_eof(); virtual bool send_eof();
#ifdef EMBEDDED_LIBRARY #ifdef EMBEDDED_LIBRARY
void begin_dataset() void begin_dataset()
...@@ -3057,7 +3057,7 @@ bool Select_fetch_protocol_binary::send_eof() ...@@ -3057,7 +3057,7 @@ bool Select_fetch_protocol_binary::send_eof()
} }
int bool
Select_fetch_protocol_binary::send_data(List<Item> &fields) Select_fetch_protocol_binary::send_data(List<Item> &fields)
{ {
Protocol *save_protocol= thd->protocol; Protocol *save_protocol= thd->protocol;
......
...@@ -2367,7 +2367,7 @@ void Show_explain_request::call_in_target_thread() ...@@ -2367,7 +2367,7 @@ void Show_explain_request::call_in_target_thread()
} }
int select_result_explain_buffer::send_data(List<Item> &items) bool select_result_explain_buffer::send_data(List<Item> &items)
{ {
int res; int res;
THD *cur_thd= current_thd; THD *cur_thd= current_thd;
...@@ -5713,16 +5713,16 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table, ...@@ -5713,16 +5713,16 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
for (uint i= 0 ; i < params ; i++) for (uint i= 0 ; i < params ; i++)
{ {
const char *tmp_buff; const char *tmp_buff;
sp_variable_t *spvar= spcont->find_variable(i); sp_variable *spvar= spcont->find_variable(i);
field_def= &spvar->field_def; field_def= &spvar->field_def;
switch (spvar->mode) { switch (spvar->mode) {
case sp_param_in: case sp_variable::MODE_IN:
tmp_buff= "IN"; tmp_buff= "IN";
break; break;
case sp_param_out: case sp_variable::MODE_OUT:
tmp_buff= "OUT"; tmp_buff= "OUT";
break; break;
case sp_param_inout: case sp_variable::MODE_INOUT:
tmp_buff= "INOUT"; tmp_buff= "INOUT";
break; break;
default: default:
......
...@@ -115,8 +115,8 @@ void Sql_cmd_common_signal::eval_defaults(THD *thd, Sql_condition *cond) ...@@ -115,8 +115,8 @@ void Sql_cmd_common_signal::eval_defaults(THD *thd, Sql_condition *cond)
/* /*
SIGNAL is restricted in sql_yacc.yy to only signal SQLSTATE conditions. SIGNAL is restricted in sql_yacc.yy to only signal SQLSTATE conditions.
*/ */
DBUG_ASSERT(m_cond->type == sp_cond_type::state); DBUG_ASSERT(m_cond->type == sp_condition_value::SQLSTATE);
sqlstate= m_cond->sqlstate; sqlstate= m_cond->sql_state;
cond->set_sqlstate(sqlstate); cond->set_sqlstate(sqlstate);
} }
else else
...@@ -488,8 +488,8 @@ bool Sql_cmd_signal::execute(THD *thd) ...@@ -488,8 +488,8 @@ bool Sql_cmd_signal::execute(THD *thd)
bool Sql_cmd_resignal::execute(THD *thd) bool Sql_cmd_resignal::execute(THD *thd)
{ {
Sql_condition_info *signaled;
Diagnostics_area *da= thd->get_stmt_da(); Diagnostics_area *da= thd->get_stmt_da();
const sp_rcontext::Sql_condition_info *signaled;
int result= TRUE; int result= TRUE;
DBUG_ENTER("Resignal_statement::execute"); DBUG_ENTER("Resignal_statement::execute");
...@@ -505,16 +505,31 @@ bool Sql_cmd_resignal::execute(THD *thd) ...@@ -505,16 +505,31 @@ bool Sql_cmd_resignal::execute(THD *thd)
} }
Sql_condition signaled_err(thd->mem_root); Sql_condition signaled_err(thd->mem_root);
signaled_err.set(signaled->m_sql_errno, signaled_err.set(signaled->sql_errno,
signaled->m_sql_state, signaled->sql_state,
signaled->m_level, signaled->level,
signaled->m_message); signaled->message);
if (m_cond == NULL) if (m_cond == NULL)
{ {
/* RESIGNAL without signal_value */ query_cache_abort(&thd->query_cache_tls);
result= raise_condition(thd, &signaled_err);
DBUG_RETURN(result); /* Keep handled conditions. */
da->unmark_sql_conditions_from_removal();
/* Check if the old condition still exists. */
if (da->has_sql_condition(signaled->message, strlen(signaled->message)))
{
/* Make room for the new RESIGNAL condition. */
da->reserve_space(thd, 1);
}
else
{
/* Make room for old condition + the new RESIGNAL condition. */
da->reserve_space(thd, 2);
da->push_warning(thd, &signaled_err);
}
} }
/* RESIGNAL with signal_value */ /* RESIGNAL with signal_value */
......
...@@ -29,7 +29,7 @@ protected: ...@@ -29,7 +29,7 @@ protected:
@param cond the condition signaled if any, or NULL. @param cond the condition signaled if any, or NULL.
@param set collection of signal condition item assignments. @param set collection of signal condition item assignments.
*/ */
Sql_cmd_common_signal(const sp_cond_type *cond, Sql_cmd_common_signal(const sp_condition_value *cond,
const Set_signal_information& set) const Set_signal_information& set)
: Sql_cmd(), : Sql_cmd(),
m_cond(cond), m_cond(cond),
...@@ -80,7 +80,7 @@ protected: ...@@ -80,7 +80,7 @@ protected:
The condition to signal or resignal. The condition to signal or resignal.
This member is optional and can be NULL (RESIGNAL). This member is optional and can be NULL (RESIGNAL).
*/ */
const sp_cond_type *m_cond; const sp_condition_value *m_cond;
/** /**
Collection of 'SET item = value' assignments in the Collection of 'SET item = value' assignments in the
...@@ -100,7 +100,7 @@ public: ...@@ -100,7 +100,7 @@ public:
@param cond the SQL condition to signal (required). @param cond the SQL condition to signal (required).
@param set the collection of signal informations to signal. @param set the collection of signal informations to signal.
*/ */
Sql_cmd_signal(const sp_cond_type *cond, Sql_cmd_signal(const sp_condition_value *cond,
const Set_signal_information& set) const Set_signal_information& set)
: Sql_cmd_common_signal(cond, set) : Sql_cmd_common_signal(cond, set)
{} {}
...@@ -127,7 +127,7 @@ public: ...@@ -127,7 +127,7 @@ public:
@param cond the SQL condition to resignal (optional, may be NULL). @param cond the SQL condition to resignal (optional, may be NULL).
@param set the collection of signal informations to resignal. @param set the collection of signal informations to resignal.
*/ */
Sql_cmd_resignal(const sp_cond_type *cond, Sql_cmd_resignal(const sp_condition_value *cond,
const Set_signal_information& set) const Set_signal_information& set)
: Sql_cmd_common_signal(cond, set) : Sql_cmd_common_signal(cond, set)
{} {}
......
...@@ -52,7 +52,7 @@ int select_union::prepare(List<Item> &list, SELECT_LEX_UNIT *u) ...@@ -52,7 +52,7 @@ int select_union::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
} }
int select_union::send_data(List<Item> &values) bool select_union::send_data(List<Item> &values)
{ {
if (unit->offset_limit_cnt) if (unit->offset_limit_cnt)
{ // using limit offset,count { // using limit offset,count
......
...@@ -1829,7 +1829,7 @@ multi_update::~multi_update() ...@@ -1829,7 +1829,7 @@ multi_update::~multi_update()
} }
int multi_update::send_data(List<Item> &not_used_values) bool multi_update::send_data(List<Item> &not_used_values)
{ {
TABLE_LIST *cur_table; TABLE_LIST *cur_table;
DBUG_ENTER("multi_update::send_data"); DBUG_ENTER("multi_update::send_data");
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment