summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/func_str.result2
-rw-r--r--sql/item.cc45
-rw-r--r--sql/item_cmpfunc.cc30
-rw-r--r--sql/item_cmpfunc.h70
-rw-r--r--sql/item_func.cc30
-rw-r--r--sql/item_func.h2
-rw-r--r--sql/item_strfunc.cc10
-rw-r--r--sql/item_subselect.cc96
-rw-r--r--sql/item_subselect.h8
-rw-r--r--sql/item_timefunc.cc6
-rw-r--r--sql/mysql_priv.h20
-rw-r--r--sql/mysqld.cc8
-rw-r--r--sql/sql_parse.cc24
-rw-r--r--sql/sql_string.cc32
-rw-r--r--sql/sql_string.h1
-rw-r--r--sql/sql_yacc.yy51
16 files changed, 238 insertions, 197 deletions
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 1a4e2fa498b..26741cff864 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -592,4 +592,4 @@ explain extended select md5('hello'), sha('abc'), sha1('abc'), soundex(''), 'moo
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select high_priority md5(_latin1'hello') AS `md5('hello')`,sha(_latin1'abc') AS `sha('abc')`,sha(_latin1'abc') AS `sha1('abc')`,soundex(_latin1'') AS `soundex('')`,(soundex(_latin1'mood') = soundex(_latin1'mud')) AS `'mood' sounds like 'mud'`,aes_decrypt(aes_encrypt(_latin1'abc',_latin1'1'),_latin1'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`,concat(_latin1'*',repeat(_latin1' ',5),_latin1'*') AS `concat('*',space(5),'*')`,reverse(_latin1'abc') AS `reverse('abc')`,rpad(_latin1'a',4,_latin1'1') AS `rpad('a',4,'1')`,lpad(_latin1'a',4,_latin1'1') AS `lpad('a',4,'1')`,concat_ws(_latin1',',_latin1'',NULL,_latin1'a') AS `concat_ws(',','',NULL,'a')`,make_set(255,_latin2'a',_latin2'b',_latin2'c') AS `make_set(255,_latin2'a',_latin2'b',_latin2'c')`,elt(2,1) AS `elt(2,1)`,locate(_latin1'a',_latin1'b',2) AS `locate("a","b",2)`,format(130,10) AS `format(130,10)`,char(0) AS `char(0)`,conv(130,16,10) AS `conv(130,16,10)`,hex(130) AS `hex(130)`,(_latin1'HE' collate _latin1'BINARY') AS `binary 'HE'`,export_set(255,_latin2'y',_latin2'n',_latin2' ') AS `export_set(255,_latin2'y',_latin2'n',_latin2' ')`,field((_latin1'b' collate _latin1'latin1_bin'),_latin1'A',_latin1'B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`,find_in_set(_latin1'B',_latin1'a,b,c,d') AS `FIND_IN_SET(_latin1'B',_latin1'a,b,c,d')`,collation(conv(130,16,10)) AS `collation(conv(130,16,10))`,coercibility(conv(130,16,10)) AS `coercibility(conv(130,16,10))`,length(_latin1'\n\t\r\b\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n\t\r\b\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n\t\r\b\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,concat(_latin1'monty',_latin1' was here ',_latin1'again') AS `concat('monty',' was here ','again')`,length(_latin1'hello') AS `length('hello')`,char(ascii(_latin1'h')) AS `char(ascii('h'))`,ord(_latin1'h') AS `ord('h')`,quote((1 / 0)) AS `quote(1/0)`,crc32(_latin1'123') AS `crc32("123")`
+Note 1003 select high_priority md5(_latin1'hello') AS `md5('hello')`,sha(_latin1'abc') AS `sha('abc')`,sha(_latin1'abc') AS `sha1('abc')`,soundex(_latin1'') AS `soundex('')`,(soundex(_latin1'mood') = soundex(_latin1'mud')) AS `'mood' sounds like 'mud'`,aes_decrypt(aes_encrypt(_latin1'abc',_latin1'1'),_latin1'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`,concat(_latin1'*',repeat(_latin1' ',5),_latin1'*') AS `concat('*',space(5),'*')`,reverse(_latin1'abc') AS `reverse('abc')`,rpad(_latin1'a',4,_latin1'1') AS `rpad('a',4,'1')`,lpad(_latin1'a',4,_latin1'1') AS `lpad('a',4,'1')`,concat_ws(_latin1',',_latin1'',NULL,_latin1'a') AS `concat_ws(',','',NULL,'a')`,make_set(255,_latin2'a',_latin2'b',_latin2'c') AS `make_set(255,_latin2'a',_latin2'b',_latin2'c')`,elt(2,1) AS `elt(2,1)`,locate(_latin1'a',_latin1'b',2) AS `locate("a","b",2)`,format(130,10) AS `format(130,10)`,char(0) AS `char(0)`,conv(130,16,10) AS `conv(130,16,10)`,hex(130) AS `hex(130)`,(_latin1'HE' collate _latin1'BINARY') AS `binary 'HE'`,export_set(255,_latin2'y',_latin2'n',_latin2' ') AS `export_set(255,_latin2'y',_latin2'n',_latin2' ')`,field((_latin1'b' collate _latin1'latin1_bin'),_latin1'A',_latin1'B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`,find_in_set(_latin1'B',_latin1'a,b,c,d') AS `FIND_IN_SET(_latin1'B',_latin1'a,b,c,d')`,collation(conv(130,16,10)) AS `collation(conv(130,16,10))`,coercibility(conv(130,16,10)) AS `coercibility(conv(130,16,10))`,length(_latin1'\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,concat(_latin1'monty',_latin1' was here ',_latin1'again') AS `concat('monty',' was here ','again')`,length(_latin1'hello') AS `length('hello')`,char(ascii(_latin1'h')) AS `char(ascii('h'))`,ord(_latin1'h') AS `ord('h')`,quote((1 / 0)) AS `quote(1/0)`,crc32(_latin1'123') AS `crc32("123")`
diff --git a/sql/item.cc b/sql/item.cc
index 29cde9375ba..421574ed636 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -455,21 +455,21 @@ Item *Item_field::get_tmp_table_item(THD *thd)
String *Item_int::val_str(String *str)
{
- str->set(value, default_charset());
+ str->set(value, &my_charset_bin);
return str;
}
void Item_int::print(String *str)
{
- // latin1 is good enough for numbers
- str_value.set(value, &my_charset_latin1);
+ // my_charset_bin is good enough for numbers
+ str_value.set(value, &my_charset_bin);
str->append(str_value);
}
String *Item_uint::val_str(String *str)
{
- str->set((ulonglong) value, default_charset());
+ str->set((ulonglong) value, &my_charset_bin);
return str;
}
@@ -484,7 +484,7 @@ void Item_uint::print(String *str)
String *Item_real::val_str(String *str)
{
- str->set(value,decimals,default_charset());
+ str->set(value,decimals,&my_charset_bin);
return str;
}
@@ -494,40 +494,7 @@ void Item_string::print(String *str)
str->append('_');
str->append(collation.collation->csname);
str->append('\'');
- char *st= (char*)str_value.ptr(), *end= st+str_value.length();
- for(; st < end; st++)
- {
- uchar c= *st;
- switch (c)
- {
- case '\\':
- str->append("\\\\", 2);
- break;
- case '\0':
- str->append("\\0", 2);
- break;
- case '\'':
- str->append("\\'", 2);
- break;
- case '\n':
- str->append("\\n", 2);
- break;
- case '\r':
- str->append("\\r", 2);
- break;
- case '\t':
- str->append("\\t", 2);
- break;
- case '\b':
- str->append("\\b", 2);
- break;
- case 26: //Ctrl-Z
- str->append("\\z", 2);
- break;
- default:
- str->append(c);
- }
- }
+ str_value.print(str);
str->append('\'');
}
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 3897022e8ce..1ec1a19382d 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -59,27 +59,38 @@ static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fnam
fname);
}
-Item_bool_func2* Item_bool_func2::eq_creator(Item *a, Item *b)
+
+Item_bool_func2* Eq_creator::create(Item *a, Item *b) const
{
return new Item_func_eq(a, b);
}
-Item_bool_func2* Item_bool_func2::ne_creator(Item *a, Item *b)
+
+
+Item_bool_func2* Ne_creator::create(Item *a, Item *b) const
{
return new Item_func_ne(a, b);
}
-Item_bool_func2* Item_bool_func2::gt_creator(Item *a, Item *b)
+
+
+Item_bool_func2* Gt_creator::create(Item *a, Item *b) const
{
return new Item_func_gt(a, b);
}
-Item_bool_func2* Item_bool_func2::lt_creator(Item *a, Item *b)
+
+
+Item_bool_func2* Lt_creator::create(Item *a, Item *b) const
{
return new Item_func_lt(a, b);
}
-Item_bool_func2* Item_bool_func2::ge_creator(Item *a, Item *b)
+
+
+Item_bool_func2* Ge_creator::create(Item *a, Item *b) const
{
return new Item_func_ge(a, b);
}
-Item_bool_func2* Item_bool_func2::le_creator(Item *a, Item *b)
+
+
+Item_bool_func2* Le_creator::create(Item *a, Item *b) const
{
return new Item_func_le(a, b);
}
@@ -1549,12 +1560,7 @@ void Item_func_in::print(String *str)
str->append('(');
args[0]->print(str);
str->append(" in (", 5);
- for (uint i=1 ; i < arg_count ; i++)
- {
- if (i > 1)
- str->append(',');
- args[i]->print(str);
- }
+ print_args(str, 1);
str->append("))", 2);
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 3f73c7736da..081374345d8 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -109,6 +109,69 @@ public:
Item_cache **get_cache() { return &cache; }
};
+class Comp_creator
+{
+public:
+ virtual Item_bool_func2* create(Item *a, Item *b) const = 0;
+ virtual const char* symbol(bool invert) const = 0;
+ virtual bool eqne_op() const = 0;
+ virtual bool l_op() const = 0;
+};
+
+class Eq_creator :public Comp_creator
+{
+public:
+ virtual Item_bool_func2* create(Item *a, Item *b) const;
+ virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
+ virtual bool eqne_op() const { return 1; }
+ virtual bool l_op() const { return 0; }
+};
+
+class Ne_creator :public Comp_creator
+{
+public:
+ virtual Item_bool_func2* create(Item *a, Item *b) const;
+ virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
+ virtual bool eqne_op() const { return 1; }
+ virtual bool l_op() const { return 0; }
+};
+
+class Gt_creator :public Comp_creator
+{
+public:
+ virtual Item_bool_func2* create(Item *a, Item *b) const;
+ virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
+ virtual bool eqne_op() const { return 0; }
+ virtual bool l_op() const { return 0; }
+};
+
+class Lt_creator :public Comp_creator
+{
+public:
+ virtual Item_bool_func2* create(Item *a, Item *b) const;
+ virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
+ virtual bool eqne_op() const { return 0; }
+ virtual bool l_op() const { return 1; }
+};
+
+class Ge_creator :public Comp_creator
+{
+public:
+ virtual Item_bool_func2* create(Item *a, Item *b) const;
+ virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
+ virtual bool eqne_op() const { return 0; }
+ virtual bool l_op() const { return 0; }
+};
+
+class Le_creator :public Comp_creator
+{
+public:
+ virtual Item_bool_func2* create(Item *a, Item *b) const;
+ virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
+ virtual bool eqne_op() const { return 0; }
+ virtual bool l_op() const { return 1; }
+};
+
class Item_bool_func2 :public Item_int_func
{ /* Bool with 2 string args */
protected:
@@ -129,13 +192,6 @@ public:
void print(String *str) { Item_func::print_op(str); }
bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
- static Item_bool_func2* eq_creator(Item *a, Item *b);
- static Item_bool_func2* ne_creator(Item *a, Item *b);
- static Item_bool_func2* gt_creator(Item *a, Item *b);
- static Item_bool_func2* lt_creator(Item *a, Item *b);
- static Item_bool_func2* ge_creator(Item *a, Item *b);
- static Item_bool_func2* le_creator(Item *a, Item *b);
-
friend class Arg_comparator;
};
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 7717eaee425..bcb4ec9aa7f 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -287,16 +287,16 @@ void Item_func::print(String *str)
{
str->append(func_name());
str->append('(');
- print_args(str);
+ print_args(str, 0);
str->append(')');
}
-void Item_func::print_args(String *str)
+void Item_func::print_args(String *str, uint from)
{
- for (uint i=0 ; i < arg_count ; i++)
+ for (uint i=from ; i < arg_count ; i++)
{
- if (i)
+ if (i != from)
str->append(',');
args[i]->print(str);
}
@@ -2092,9 +2092,9 @@ void Item_func_benchmark::print(String *str)
{
str->append("benchmark(", 10);
char buffer[20];
- // latin1 is good enough for numbers
- String st(buffer, sizeof(buffer), &my_charset_latin1);
- st.set((ulonglong)loop_count, &my_charset_latin1);
+ // my_charset_bin is good enough for numbers
+ String st(buffer, sizeof(buffer), &my_charset_bin);
+ st.set((ulonglong)loop_count, &my_charset_bin);
str->append(st);
str->append(',');
args[0]->print(str);
@@ -2870,21 +2870,13 @@ double Item_func_match::val()
void Item_func_match::print(String *str)
{
str->append("(match ", 7);
- List_iterator_fast<Item> li(fields);
- Item *item;
- bool first= 1;
- while ((item= li++))
- {
- if (first)
- first= 0;
- else
- str->append(',');
- item->print(str);
- }
+ print_args(str, 1);
str->append(" against (", 10);
args[0]->print(str);
- if (mode == FT_BOOL)
+ if (flags & FT_BOOL)
str->append(" in boolean mode", 16);
+ else if (flags & FT_EXPAND)
+ str->append(" with query expansion", 21);
str->append("))", 2);
}
diff --git a/sql/item_func.h b/sql/item_func.h
index cee1d73847a..b9498ed0b5d 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -125,7 +125,7 @@ public:
virtual void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
void print(String *str);
void print_op(String *str);
- void print_args(String *str);
+ void print_args(String *str, uint from);
void fix_num_length_and_dec();
inline bool get_arg0_date(TIME *ltime,bool fuzzy_date)
{
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 70f98783624..310faae8380 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -661,7 +661,7 @@ void Item_func_concat_ws::print(String *str)
if (arg_count)
{
str->append(',');
- print_args(str);
+ print_args(str, 0);
}
str->append(')');
}
@@ -1629,10 +1629,10 @@ void Item_func_format::print(String *str)
str->append("format(", 7);
args[0]->print(str);
str->append(',');
- // latin1 is good enough for numbers
+ // my_charset_bin is good enough for numbers
char buffer[20];
- String st(buffer, sizeof(buffer), &my_charset_latin1);
- st.set((ulonglong)decimals, &my_charset_latin1);
+ String st(buffer, sizeof(buffer), &my_charset_bin);
+ st.set((ulonglong)decimals, &my_charset_bin);
str->append(st);
str->append(')');
}
@@ -1795,7 +1795,7 @@ void Item_func_make_set::print(String *str)
if (arg_count)
{
str->append(',');
- print_args(str);
+ print_args(str, 0);
}
str->append(')');
}
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index d43978db0d5..9fd6dab83f6 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -440,7 +440,7 @@ Item_in_subselect::Item_in_subselect(Item * left_exp,
}
Item_allany_subselect::Item_allany_subselect(Item * left_exp,
- compare_func_creator fn,
+ Comp_creator *fn,
st_select_lex *select_lex,
bool all_arg)
:Item_in_subselect(), all(all_arg)
@@ -542,7 +542,7 @@ String *Item_in_subselect::val_str(String *str)
Item_subselect::trans_res
Item_in_subselect::single_value_transformer(JOIN *join,
- compare_func_creator func)
+ Comp_creator *func)
{
DBUG_ENTER("Item_in_subselect::single_value_transformer");
@@ -558,11 +558,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
}
if ((abort_on_null || (upper_not && upper_not->top_level())) &&
- !select_lex->master_unit()->dependent &&
- (func == &Item_bool_func2::gt_creator ||
- func == &Item_bool_func2::lt_creator ||
- func == &Item_bool_func2::ge_creator ||
- func == &Item_bool_func2::le_creator))
+ !select_lex->master_unit()->dependent && !func->eqne_op())
{
if (substitution)
{
@@ -577,8 +573,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
{
Item *item;
subs_type type= substype();
- if (func == &Item_bool_func2::le_creator ||
- func == &Item_bool_func2::lt_creator)
+ if (func->l_op())
{
/*
(ALL && (> || =>)) || (ANY && (< || =<))
@@ -609,9 +604,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
// remove LIMIT placed by ALL/ANY subquery
select_lex->master_unit()->global_parameters->select_limit=
HA_POS_ERROR;
- subs= new Item_maxmin_subselect(this, select_lex,
- (func == &Item_bool_func2::le_creator ||
- func == &Item_bool_func2::lt_creator));
+ subs= new Item_maxmin_subselect(this, select_lex, func->l_op());
}
// left expression belong to outer select
SELECT_LEX *current= thd->lex.current_select, *up;
@@ -622,7 +615,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
DBUG_RETURN(RES_ERROR);
}
thd->lex.current_select= current;
- substitution= (*func)(left_expr, subs);
+ substitution= func->create(left_expr, subs);
DBUG_RETURN(RES_OK);
}
@@ -662,11 +655,11 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (join->having || select_lex->with_sum_func ||
select_lex->group_list.elements)
{
- item= (*func)(expr,
- new Item_ref_null_helper(this,
- select_lex->ref_pointer_array,
- (char *)"<ref>",
- this->full_name()));
+ item= func->create(expr,
+ new Item_ref_null_helper(this,
+ select_lex->ref_pointer_array,
+ (char *)"<ref>",
+ this->full_name()));
join->having= and_items(join->having, item);
select_lex->having_fix_field= 1;
if (join->having->fix_fields(thd, join->tables_list, &join->having))
@@ -685,7 +678,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (select_lex->table_list.elements)
{
Item *having= item, *isnull= item;
- item= (*func)(expr, item);
+ item= func->create(expr, item);
if (!abort_on_null)
{
having= new Item_is_not_null_test(this, having);
@@ -711,10 +704,10 @@ Item_in_subselect::single_value_transformer(JOIN *join,
{
if (select_lex->master_unit()->first_select()->next_select())
{
- join->having= (*func)(expr,
- new Item_null_helper(this, item,
- (char *)"<no matter>",
- (char *)"<result>"));
+ join->having= func->create(expr,
+ new Item_null_helper(this, item,
+ (char *)"<no matter>",
+ (char *)"<result>"));
select_lex->having_fix_field= 1;
if (join->having->fix_fields(thd, join->tables_list, &join->having))
{
@@ -726,7 +719,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
else
{
// it is single select without tables => possible optimization
- item= (*func)(left_expr, item);
+ item= func->create(left_expr, item);
// fix_field of item will be done in time of substituting
substitution= item;
have_to_be_excluded= 1;
@@ -793,11 +786,11 @@ Item_in_subselect::row_value_transformer(JOIN *join)
(char *) "<no matter>",
(char *) "<list ref>");
func=
- Item_bool_func2::eq_creator(new Item_ref((*optimizer->get_cache())->
- addr(i),
- (char *)"<no matter>",
- (char *)in_left_expr_name),
- func);
+ eq_creator.create(new Item_ref((*optimizer->get_cache())->
+ addr(i),
+ (char *)"<no matter>",
+ (char *)in_left_expr_name),
+ func);
item= and_items(item, func);
}
@@ -829,8 +822,7 @@ Item_in_subselect::select_transformer(JOIN *join)
{
transformed= 1;
if (left_expr->cols() == 1)
- return single_value_transformer(join,
- &Item_bool_func2::eq_creator);
+ return single_value_transformer(join, &eq_creator);
return row_value_transformer(join);
}
@@ -866,46 +858,8 @@ void Item_allany_subselect::print(String *str)
{
left_expr->print(str);
str->append(' ');
- if (all)
- {
- if (func == &Item_bool_func2::lt_creator)
- str->append(">=", 2);
- else if (func == &Item_bool_func2::gt_creator)
- str->append("<=", 2);
- else if (func == &Item_bool_func2::le_creator)
- str->append('>');
- else if (func == &Item_bool_func2::ge_creator)
- str->append('<');
- else if (func == &Item_bool_func2::eq_creator)
- str->append("<>", 2);
- else if (func == &Item_bool_func2::ne_creator)
- str->append('=');
- else
- {
- DBUG_ASSERT(0); // Impossible
- }
- str->append(" all ", 5);
- }
- else
- {
- if (func == &Item_bool_func2::lt_creator)
- str->append('<');
- else if (func == &Item_bool_func2::gt_creator)
- str->append('>');
- else if (func == &Item_bool_func2::le_creator)
- str->append("<=", 2);
- else if (func == &Item_bool_func2::ge_creator)
- str->append(">=", 2);
- else if (func == &Item_bool_func2::eq_creator)
- str->append('=');
- else if (func == &Item_bool_func2::ne_creator)
- str->append("<>", 2);
- else
- {
- DBUG_ASSERT(0); // Impossible
- }
- str->append(" any ", 5);
- }
+ str->append(func->symbol(all));
+ str->append(all ? " all " : " any ", 5);
}
Item_subselect::print(str);
}
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 26e165df3d3..712b3de42ad 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -27,8 +27,6 @@ class select_subselect;
class subselect_engine;
class Item_bool_func2;
-typedef Item_bool_func2* (*compare_func_creator)(Item*, Item*);
-
/* base class for subselects */
class Item_subselect :public Item_result_field
@@ -210,7 +208,7 @@ public:
}
trans_res select_transformer(JOIN *join);
trans_res single_value_transformer(JOIN *join,
- compare_func_creator func);
+ Comp_creator *func);
trans_res row_value_transformer(JOIN * join);
longlong val_int();
double val();
@@ -229,12 +227,12 @@ public:
class Item_allany_subselect :public Item_in_subselect
{
protected:
- compare_func_creator func;
+ Comp_creator *func;
public:
bool all;
- Item_allany_subselect(Item * left_expr, compare_func_creator f,
+ Item_allany_subselect(Item * left_expr, Comp_creator *f,
st_select_lex *select_lex, bool all);
// only ALL subquery has upper not
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 4f1d6c5d63e..46d39b4ced6 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1797,9 +1797,9 @@ void Item_char_typecast::print(String *str)
{
str->append('(');
char buffer[20];
- // latin1 is good enough for numbers
- String st(buffer, sizeof(buffer), &my_charset_latin1);
- st.set((ulonglong)cast_length, &my_charset_latin1);
+ // my_charset_bin is good enough for numbers
+ String st(buffer, sizeof(buffer), &my_charset_bin);
+ st.set((ulonglong)cast_length, &my_charset_bin);
str->append(st);
str->append(')');
}
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 72cfd6ee56e..f71fca29f56 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -338,7 +338,7 @@ inline THD *_current_thd(void)
#include "protocol.h"
#include "sql_udf.h"
#include "item.h"
-typedef compare_func_creator (*chooser_compare_func_creator)(bool invert);
+typedef Comp_creator* (*chooser_compare_func_creator)(bool invert);
#include "sql_class.h"
#include "opt_range.h"
@@ -770,6 +770,12 @@ extern const char *first_keyword, *my_localhost, *delayed_user, *binary_keyword;
extern const char **errmesg; /* Error messages */
extern const char *myisam_recover_options_str;
extern const char *in_left_expr_name, *in_additional_cond;
+extern Eq_creator eq_creator;
+extern Ne_creator ne_creator;
+extern Gt_creator gt_creator;
+extern Lt_creator lt_creator;
+extern Ge_creator ge_creator;
+extern Le_creator le_creator;
extern uchar *days_in_month;
extern char language[LIBLEN],reg_ext[FN_EXTLEN];
extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
@@ -1059,12 +1065,12 @@ inline void table_case_convert(char * name, uint length)
my_casedn(files_charset_info, name, length);
}
-compare_func_creator comp_eq_creator(bool invert);
-compare_func_creator comp_ge_creator(bool invert);
-compare_func_creator comp_gt_creator(bool invert);
-compare_func_creator comp_le_creator(bool invert);
-compare_func_creator comp_lt_creator(bool invert);
-compare_func_creator comp_ne_creator(bool invert);
+Comp_creator *comp_eq_creator(bool invert);
+Comp_creator *comp_ge_creator(bool invert);
+Comp_creator *comp_gt_creator(bool invert);
+Comp_creator *comp_le_creator(bool invert);
+Comp_creator *comp_lt_creator(bool invert);
+Comp_creator *comp_ne_creator(bool invert);
Item * all_any_subquery_creator(Item *left_expr,
chooser_compare_func_creator cmp,
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 75e2fc957e4..eb632912575 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -335,6 +335,14 @@ const char *sql_mode_str="OFF";
const char *in_left_expr_name= "<left expr>";
/* name of additional condition */
const char *in_additional_cond= "<IN COND>";
+/* classes for comparation parsing/processing */
+Eq_creator eq_creator;
+Ne_creator ne_creator;
+Gt_creator gt_creator;
+Lt_creator lt_creator;
+Ge_creator ge_creator;
+Le_creator le_creator;
+
FILE *bootstrap_file;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 5a69a3a1017..f377714461d 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4636,39 +4636,39 @@ bool check_simple_select()
}
-compare_func_creator comp_eq_creator(bool invert)
+Comp_creator *comp_eq_creator(bool invert)
{
- return invert?&Item_bool_func2::ne_creator:&Item_bool_func2::eq_creator;
+ return invert?(Comp_creator *)&ne_creator:(Comp_creator *)&eq_creator;
}
-compare_func_creator comp_ge_creator(bool invert)
+Comp_creator *comp_ge_creator(bool invert)
{
- return invert?&Item_bool_func2::lt_creator:&Item_bool_func2::ge_creator;
+ return invert?(Comp_creator *)&lt_creator:(Comp_creator *)&ge_creator;
}
-compare_func_creator comp_gt_creator(bool invert)
+Comp_creator *comp_gt_creator(bool invert)
{
- return invert?&Item_bool_func2::le_creator:&Item_bool_func2::gt_creator;
+ return invert?(Comp_creator *)&le_creator:(Comp_creator *)&gt_creator;
}
-compare_func_creator comp_le_creator(bool invert)
+Comp_creator *comp_le_creator(bool invert)
{
- return invert?&Item_bool_func2::gt_creator:&Item_bool_func2::le_creator;
+ return invert?(Comp_creator *)&gt_creator:(Comp_creator *)&le_creator;
}
-compare_func_creator comp_lt_creator(bool invert)
+Comp_creator *comp_lt_creator(bool invert)
{
- return invert?&Item_bool_func2::ge_creator:&Item_bool_func2::lt_creator;
+ return invert?(Comp_creator *)&ge_creator:(Comp_creator *)&lt_creator;
}
-compare_func_creator comp_ne_creator(bool invert)
+Comp_creator *comp_ne_creator(bool invert)
{
- return invert?&Item_bool_func2::eq_creator:&Item_bool_func2::ne_creator;
+ return invert?(Comp_creator *)&eq_creator:(Comp_creator *)&ne_creator;
}
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index be9404ce0b8..61070f07266 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -680,3 +680,35 @@ outp:
}
return (uint32) (to - to_start);
}
+
+void String::print(String *str)
+{
+ char *st= (char*)Ptr, *end= st+str_length;
+ for(; st < end; st++)
+ {
+ uchar c= *st;
+ switch (c)
+ {
+ case '\\':
+ str->append("\\\\", 2);
+ break;
+ case '\0':
+ str->append("\\0", 2);
+ break;
+ case '\'':
+ str->append("\\'", 2);
+ break;
+ case '\n':
+ str->append("\\n", 2);
+ break;
+ case '\r':
+ str->append("\\r", 2);
+ break;
+ case 26: //Ctrl-Z
+ str->append("\\z", 2);
+ break;
+ default:
+ str->append(c);
+ }
+ }
+}
diff --git a/sql/sql_string.h b/sql/sql_string.h
index d446d26298b..325611737ca 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -289,4 +289,5 @@ public:
str_length+= arg_length;
return FALSE;
}
+ void print(String *print);
};
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 997e2122e2b..2036d13232f 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -2304,15 +2304,22 @@ expr_expr:
| expr OR expr { $$= new Item_cond_or($1,$3); }
| expr XOR expr { $$= new Item_cond_xor($1,$3); }
| expr AND expr { $$= new Item_cond_and($1,$3); }
- | expr SOUNDS_SYM LIKE expr { $$= Item_bool_func2::eq_creator(new Item_func_soundex($1), new Item_func_soundex($4));}
- | expr LIKE simple_expr opt_escape { $$= new Item_func_like($1,$3,$4); }
- | expr NOT LIKE simple_expr opt_escape { $$= new Item_func_not(new Item_func_like($1,$4,$5));}
+ | expr SOUNDS_SYM LIKE expr
+ {
+ $$= new Item_func_eq(new Item_func_soundex($1),
+ new Item_func_soundex($4));
+ }
+ | expr LIKE simple_expr opt_escape
+ { $$= new Item_func_like($1,$3,$4); }
+ | expr NOT LIKE simple_expr opt_escape
+ { $$= new Item_func_not(new Item_func_like($1,$4,$5));}
| expr REGEXP expr { $$= new Item_func_regex($1,$3); }
- | expr NOT REGEXP expr { $$= new Item_func_not(new Item_func_regex($1,$4)); }
+ | expr NOT REGEXP expr
+ { $$= new Item_func_not(new Item_func_regex($1,$4)); }
| expr IS NULL_SYM { $$= new Item_func_isnull($1); }
| expr IS NOT NULL_SYM { $$= new Item_func_isnotnull($1); }
| expr EQUAL_SYM expr { $$= new Item_func_equal($1,$3); }
- | expr comp_op expr %prec EQ { $$= (*((*$2)(0)))($1,$3); }
+ | expr comp_op expr %prec EQ { $$= (*$2)(0)->create($1,$3); }
| expr comp_op all_or_any in_subselect %prec EQ
{
$$= all_any_subquery_creator($1, $2, $3, $4);
@@ -2345,15 +2352,22 @@ no_in_expr:
| no_in_expr OR expr { $$= new Item_cond_or($1,$3); }
| no_in_expr XOR expr { $$= new Item_cond_xor($1,$3); }
| no_in_expr AND expr { $$= new Item_cond_and($1,$3); }
- | no_in_expr SOUNDS_SYM LIKE expr { $$= Item_bool_func2::eq_creator(new Item_func_soundex($1), new Item_func_soundex($4));}
- | no_in_expr LIKE simple_expr opt_escape { $$= new Item_func_like($1,$3,$4); }
- | no_in_expr NOT LIKE simple_expr opt_escape { $$= new Item_func_not(new Item_func_like($1,$4,$5)); }
+ | no_in_expr SOUNDS_SYM LIKE expr
+ {
+ $$= new Item_func_eq(new Item_func_soundex($1),
+ new Item_func_soundex($4));
+ }
+ | no_in_expr LIKE simple_expr opt_escape
+ { $$= new Item_func_like($1,$3,$4); }
+ | no_in_expr NOT LIKE simple_expr opt_escape
+ { $$= new Item_func_not(new Item_func_like($1,$4,$5)); }
| no_in_expr REGEXP expr { $$= new Item_func_regex($1,$3); }
- | no_in_expr NOT REGEXP expr { $$= new Item_func_not(new Item_func_regex($1,$4)); }
+ | no_in_expr NOT REGEXP expr
+ { $$= new Item_func_not(new Item_func_regex($1,$4)); }
| no_in_expr IS NULL_SYM { $$= new Item_func_isnull($1); }
| no_in_expr IS NOT NULL_SYM { $$= new Item_func_isnotnull($1); }
| no_in_expr EQUAL_SYM expr { $$= new Item_func_equal($1,$3); }
- | no_in_expr comp_op expr %prec EQ { $$= (*((*$2)(0)))($1,$3); }
+ | no_in_expr comp_op expr %prec EQ { $$= (*$2)(0)->create($1,$3); }
| no_in_expr comp_op all_or_any in_subselect %prec EQ
{
all_any_subquery_creator($1, $2, $3, $4);
@@ -2395,15 +2409,22 @@ no_and_expr:
| no_and_expr OR_OR_CONCAT expr { $$= or_or_concat(YYTHD, $1,$3); }
| no_and_expr OR expr { $$= new Item_cond_or($1,$3); }
| no_and_expr XOR expr { $$= new Item_cond_xor($1,$3); }
- | no_and_expr SOUNDS_SYM LIKE expr { $$= Item_bool_func2::eq_creator(new Item_func_soundex($1), new Item_func_soundex($4));}
- | no_and_expr LIKE simple_expr opt_escape { $$= new Item_func_like($1,$3,$4); }
- | no_and_expr NOT LIKE simple_expr opt_escape { $$= new Item_func_not(new Item_func_like($1,$4,$5)); }
+ | no_and_expr SOUNDS_SYM LIKE expr
+ {
+ $$= new Item_func_eq(new Item_func_soundex($1),
+ new Item_func_soundex($4));
+ }
+ | no_and_expr LIKE simple_expr opt_escape
+ { $$= new Item_func_like($1,$3,$4); }
+ | no_and_expr NOT LIKE simple_expr opt_escape
+ { $$= new Item_func_not(new Item_func_like($1,$4,$5)); }
| no_and_expr REGEXP expr { $$= new Item_func_regex($1,$3); }
- | no_and_expr NOT REGEXP expr { $$= new Item_func_not(new Item_func_regex($1,$4)); }
+ | no_and_expr NOT REGEXP expr
+ { $$= new Item_func_not(new Item_func_regex($1,$4)); }
| no_and_expr IS NULL_SYM { $$= new Item_func_isnull($1); }
| no_and_expr IS NOT NULL_SYM { $$= new Item_func_isnotnull($1); }
| no_and_expr EQUAL_SYM expr { $$= new Item_func_equal($1,$3); }
- | no_and_expr comp_op expr %prec EQ { $$= (*((*$2)(0)))($1,$3); }
+ | no_and_expr comp_op expr %prec EQ { $$= (*$2)(0)->create($1,$3); }
| no_and_expr comp_op all_or_any in_subselect %prec EQ
{
all_any_subquery_creator($1, $2, $3, $4);