Commit c56e75e2 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

after review fix

parent e025adb4
...@@ -592,4 +592,4 @@ explain extended select md5('hello'), sha('abc'), sha1('abc'), soundex(''), 'moo ...@@ -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 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 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings: 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")`
...@@ -455,21 +455,21 @@ Item *Item_field::get_tmp_table_item(THD *thd) ...@@ -455,21 +455,21 @@ Item *Item_field::get_tmp_table_item(THD *thd)
String *Item_int::val_str(String *str) String *Item_int::val_str(String *str)
{ {
str->set(value, default_charset()); str->set(value, &my_charset_bin);
return str; return str;
} }
void Item_int::print(String *str) void Item_int::print(String *str)
{ {
// latin1 is good enough for numbers // my_charset_bin is good enough for numbers
str_value.set(value, &my_charset_latin1); str_value.set(value, &my_charset_bin);
str->append(str_value); str->append(str_value);
} }
String *Item_uint::val_str(String *str) String *Item_uint::val_str(String *str)
{ {
str->set((ulonglong) value, default_charset()); str->set((ulonglong) value, &my_charset_bin);
return str; return str;
} }
...@@ -484,7 +484,7 @@ void Item_uint::print(String *str) ...@@ -484,7 +484,7 @@ void Item_uint::print(String *str)
String *Item_real::val_str(String *str) String *Item_real::val_str(String *str)
{ {
str->set(value,decimals,default_charset()); str->set(value,decimals,&my_charset_bin);
return str; return str;
} }
...@@ -494,40 +494,7 @@ void Item_string::print(String *str) ...@@ -494,40 +494,7 @@ void Item_string::print(String *str)
str->append('_'); str->append('_');
str->append(collation.collation->csname); str->append(collation.collation->csname);
str->append('\''); str->append('\'');
char *st= (char*)str_value.ptr(), *end= st+str_value.length(); str_value.print(str);
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->append('\''); str->append('\'');
} }
......
...@@ -59,27 +59,38 @@ static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fnam ...@@ -59,27 +59,38 @@ static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fnam
fname); 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); 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); 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); 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); 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); 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); return new Item_func_le(a, b);
} }
...@@ -1549,12 +1560,7 @@ void Item_func_in::print(String *str) ...@@ -1549,12 +1560,7 @@ void Item_func_in::print(String *str)
str->append('('); str->append('(');
args[0]->print(str); args[0]->print(str);
str->append(" in (", 5); str->append(" in (", 5);
for (uint i=1 ; i < arg_count ; i++) print_args(str, 1);
{
if (i > 1)
str->append(',');
args[i]->print(str);
}
str->append("))", 2); str->append("))", 2);
} }
......
...@@ -109,6 +109,69 @@ public: ...@@ -109,6 +109,69 @@ public:
Item_cache **get_cache() { return &cache; } 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 class Item_bool_func2 :public Item_int_func
{ /* Bool with 2 string args */ { /* Bool with 2 string args */
protected: protected:
...@@ -129,13 +192,6 @@ public: ...@@ -129,13 +192,6 @@ public:
void print(String *str) { Item_func::print_op(str); } void print(String *str) { Item_func::print_op(str); }
bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); } 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; friend class Arg_comparator;
}; };
......
...@@ -287,16 +287,16 @@ void Item_func::print(String *str) ...@@ -287,16 +287,16 @@ void Item_func::print(String *str)
{ {
str->append(func_name()); str->append(func_name());
str->append('('); str->append('(');
print_args(str); print_args(str, 0);
str->append(')'); 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(','); str->append(',');
args[i]->print(str); args[i]->print(str);
} }
...@@ -2092,9 +2092,9 @@ void Item_func_benchmark::print(String *str) ...@@ -2092,9 +2092,9 @@ void Item_func_benchmark::print(String *str)
{ {
str->append("benchmark(", 10); str->append("benchmark(", 10);
char buffer[20]; char buffer[20];
// latin1 is good enough for numbers // my_charset_bin is good enough for numbers
String st(buffer, sizeof(buffer), &my_charset_latin1); String st(buffer, sizeof(buffer), &my_charset_bin);
st.set((ulonglong)loop_count, &my_charset_latin1); st.set((ulonglong)loop_count, &my_charset_bin);
str->append(st); str->append(st);
str->append(','); str->append(',');
args[0]->print(str); args[0]->print(str);
...@@ -2870,21 +2870,13 @@ double Item_func_match::val() ...@@ -2870,21 +2870,13 @@ double Item_func_match::val()
void Item_func_match::print(String *str) void Item_func_match::print(String *str)
{ {
str->append("(match ", 7); str->append("(match ", 7);
List_iterator_fast<Item> li(fields); print_args(str, 1);
Item *item;
bool first= 1;
while ((item= li++))
{
if (first)
first= 0;
else
str->append(',');
item->print(str);
}
str->append(" against (", 10); str->append(" against (", 10);
args[0]->print(str); args[0]->print(str);
if (mode == FT_BOOL) if (flags & FT_BOOL)
str->append(" in boolean mode", 16); str->append(" in boolean mode", 16);
else if (flags & FT_EXPAND)
str->append(" with query expansion", 21);
str->append("))", 2); str->append("))", 2);
} }
......
...@@ -125,7 +125,7 @@ public: ...@@ -125,7 +125,7 @@ public:
virtual void split_sum_func(Item **ref_pointer_array, List<Item> &fields); virtual void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
void print(String *str); void print(String *str);
void print_op(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(); void fix_num_length_and_dec();
inline bool get_arg0_date(TIME *ltime,bool fuzzy_date) inline bool get_arg0_date(TIME *ltime,bool fuzzy_date)
{ {
......
...@@ -661,7 +661,7 @@ void Item_func_concat_ws::print(String *str) ...@@ -661,7 +661,7 @@ void Item_func_concat_ws::print(String *str)
if (arg_count) if (arg_count)
{ {
str->append(','); str->append(',');
print_args(str); print_args(str, 0);
} }
str->append(')'); str->append(')');
} }
...@@ -1629,10 +1629,10 @@ void Item_func_format::print(String *str) ...@@ -1629,10 +1629,10 @@ void Item_func_format::print(String *str)
str->append("format(", 7); str->append("format(", 7);
args[0]->print(str); args[0]->print(str);
str->append(','); str->append(',');
// latin1 is good enough for numbers // my_charset_bin is good enough for numbers
char buffer[20]; char buffer[20];
String st(buffer, sizeof(buffer), &my_charset_latin1); String st(buffer, sizeof(buffer), &my_charset_bin);
st.set((ulonglong)decimals, &my_charset_latin1); st.set((ulonglong)decimals, &my_charset_bin);
str->append(st); str->append(st);
str->append(')'); str->append(')');
} }
...@@ -1795,7 +1795,7 @@ void Item_func_make_set::print(String *str) ...@@ -1795,7 +1795,7 @@ void Item_func_make_set::print(String *str)
if (arg_count) if (arg_count)
{ {
str->append(','); str->append(',');
print_args(str); print_args(str, 0);
} }
str->append(')'); str->append(')');
} }
......
...@@ -440,7 +440,7 @@ Item_in_subselect::Item_in_subselect(Item * left_exp, ...@@ -440,7 +440,7 @@ Item_in_subselect::Item_in_subselect(Item * left_exp,
} }
Item_allany_subselect::Item_allany_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, st_select_lex *select_lex,
bool all_arg) bool all_arg)
:Item_in_subselect(), all(all_arg) :Item_in_subselect(), all(all_arg)
...@@ -542,7 +542,7 @@ String *Item_in_subselect::val_str(String *str) ...@@ -542,7 +542,7 @@ String *Item_in_subselect::val_str(String *str)
Item_subselect::trans_res Item_subselect::trans_res
Item_in_subselect::single_value_transformer(JOIN *join, Item_in_subselect::single_value_transformer(JOIN *join,
compare_func_creator func) Comp_creator *func)
{ {
DBUG_ENTER("Item_in_subselect::single_value_transformer"); DBUG_ENTER("Item_in_subselect::single_value_transformer");
...@@ -558,11 +558,7 @@ Item_in_subselect::single_value_transformer(JOIN *join, ...@@ -558,11 +558,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
} }
if ((abort_on_null || (upper_not && upper_not->top_level())) && if ((abort_on_null || (upper_not && upper_not->top_level())) &&
!select_lex->master_unit()->dependent && !select_lex->master_unit()->dependent && !func->eqne_op())
(func == &Item_bool_func2::gt_creator ||
func == &Item_bool_func2::lt_creator ||
func == &Item_bool_func2::ge_creator ||
func == &Item_bool_func2::le_creator))
{ {
if (substitution) if (substitution)
{ {
...@@ -577,8 +573,7 @@ Item_in_subselect::single_value_transformer(JOIN *join, ...@@ -577,8 +573,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
{ {
Item *item; Item *item;
subs_type type= substype(); subs_type type= substype();
if (func == &Item_bool_func2::le_creator || if (func->l_op())
func == &Item_bool_func2::lt_creator)
{ {
/* /*
(ALL && (> || =>)) || (ANY && (< || =<)) (ALL && (> || =>)) || (ANY && (< || =<))
...@@ -609,9 +604,7 @@ Item_in_subselect::single_value_transformer(JOIN *join, ...@@ -609,9 +604,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
// remove LIMIT placed by ALL/ANY subquery // remove LIMIT placed by ALL/ANY subquery
select_lex->master_unit()->global_parameters->select_limit= select_lex->master_unit()->global_parameters->select_limit=
HA_POS_ERROR; HA_POS_ERROR;
subs= new Item_maxmin_subselect(this, select_lex, subs= new Item_maxmin_subselect(this, select_lex, func->l_op());
(func == &Item_bool_func2::le_creator ||
func == &Item_bool_func2::lt_creator));
} }
// left expression belong to outer select // left expression belong to outer select
SELECT_LEX *current= thd->lex.current_select, *up; SELECT_LEX *current= thd->lex.current_select, *up;
...@@ -622,7 +615,7 @@ Item_in_subselect::single_value_transformer(JOIN *join, ...@@ -622,7 +615,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
DBUG_RETURN(RES_ERROR); DBUG_RETURN(RES_ERROR);
} }
thd->lex.current_select= current; thd->lex.current_select= current;
substitution= (*func)(left_expr, subs); substitution= func->create(left_expr, subs);
DBUG_RETURN(RES_OK); DBUG_RETURN(RES_OK);
} }
...@@ -662,11 +655,11 @@ Item_in_subselect::single_value_transformer(JOIN *join, ...@@ -662,11 +655,11 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (join->having || select_lex->with_sum_func || if (join->having || select_lex->with_sum_func ||
select_lex->group_list.elements) select_lex->group_list.elements)
{ {
item= (*func)(expr, item= func->create(expr,
new Item_ref_null_helper(this, new Item_ref_null_helper(this,
select_lex->ref_pointer_array, select_lex->ref_pointer_array,
(char *)"<ref>", (char *)"<ref>",
this->full_name())); this->full_name()));
join->having= and_items(join->having, item); join->having= and_items(join->having, item);
select_lex->having_fix_field= 1; select_lex->having_fix_field= 1;
if (join->having->fix_fields(thd, join->tables_list, &join->having)) if (join->having->fix_fields(thd, join->tables_list, &join->having))
...@@ -685,7 +678,7 @@ Item_in_subselect::single_value_transformer(JOIN *join, ...@@ -685,7 +678,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (select_lex->table_list.elements) if (select_lex->table_list.elements)
{ {
Item *having= item, *isnull= item; Item *having= item, *isnull= item;
item= (*func)(expr, item); item= func->create(expr, item);
if (!abort_on_null) if (!abort_on_null)
{ {
having= new Item_is_not_null_test(this, having); having= new Item_is_not_null_test(this, having);
...@@ -711,10 +704,10 @@ Item_in_subselect::single_value_transformer(JOIN *join, ...@@ -711,10 +704,10 @@ Item_in_subselect::single_value_transformer(JOIN *join,
{ {
if (select_lex->master_unit()->first_select()->next_select()) if (select_lex->master_unit()->first_select()->next_select())
{ {
join->having= (*func)(expr, join->having= func->create(expr,
new Item_null_helper(this, item, new Item_null_helper(this, item,
(char *)"<no matter>", (char *)"<no matter>",
(char *)"<result>")); (char *)"<result>"));
select_lex->having_fix_field= 1; select_lex->having_fix_field= 1;
if (join->having->fix_fields(thd, join->tables_list, &join->having)) if (join->having->fix_fields(thd, join->tables_list, &join->having))
{ {
...@@ -726,7 +719,7 @@ Item_in_subselect::single_value_transformer(JOIN *join, ...@@ -726,7 +719,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
else else
{ {
// it is single select without tables => possible optimization // 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 // fix_field of item will be done in time of substituting
substitution= item; substitution= item;
have_to_be_excluded= 1; have_to_be_excluded= 1;
...@@ -793,11 +786,11 @@ Item_in_subselect::row_value_transformer(JOIN *join) ...@@ -793,11 +786,11 @@ Item_in_subselect::row_value_transformer(JOIN *join)
(char *) "<no matter>", (char *) "<no matter>",
(char *) "<list ref>"); (char *) "<list ref>");
func= func=
Item_bool_func2::eq_creator(new Item_ref((*optimizer->get_cache())-> eq_creator.create(new Item_ref((*optimizer->get_cache())->
addr(i), addr(i),
(char *)"<no matter>", (char *)"<no matter>",
(char *)in_left_expr_name), (char *)in_left_expr_name),
func); func);
item= and_items(item, func); item= and_items(item, func);
} }
...@@ -829,8 +822,7 @@ Item_in_subselect::select_transformer(JOIN *join) ...@@ -829,8 +822,7 @@ Item_in_subselect::select_transformer(JOIN *join)
{ {
transformed= 1; transformed= 1;
if (left_expr->cols() == 1) if (left_expr->cols() == 1)
return single_value_transformer(join, return single_value_transformer(join, &eq_creator);
&Item_bool_func2::eq_creator);
return row_value_transformer(join); return row_value_transformer(join);
} }
...@@ -866,46 +858,8 @@ void Item_allany_subselect::print(String *str) ...@@ -866,46 +858,8 @@ void Item_allany_subselect::print(String *str)
{ {
left_expr->print(str); left_expr->print(str);
str->append(' '); str->append(' ');
if (all) str->append(func->symbol(all));
{ str->append(all ? " all " : " any ", 5);
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);
}
} }
Item_subselect::print(str); Item_subselect::print(str);
} }
......
...@@ -27,8 +27,6 @@ class select_subselect; ...@@ -27,8 +27,6 @@ class select_subselect;
class subselect_engine; class subselect_engine;
class Item_bool_func2; class Item_bool_func2;
typedef Item_bool_func2* (*compare_func_creator)(Item*, Item*);
/* base class for subselects */ /* base class for subselects */
class Item_subselect :public Item_result_field class Item_subselect :public Item_result_field
...@@ -210,7 +208,7 @@ public: ...@@ -210,7 +208,7 @@ public:
} }
trans_res select_transformer(JOIN *join); trans_res select_transformer(JOIN *join);
trans_res single_value_transformer(JOIN *join, trans_res single_value_transformer(JOIN *join,
compare_func_creator func); Comp_creator *func);
trans_res row_value_transformer(JOIN * join); trans_res row_value_transformer(JOIN * join);
longlong val_int(); longlong val_int();
double val(); double val();
...@@ -229,12 +227,12 @@ public: ...@@ -229,12 +227,12 @@ public:
class Item_allany_subselect :public Item_in_subselect class Item_allany_subselect :public Item_in_subselect
{ {
protected: protected:
compare_func_creator func; Comp_creator *func;
public: public:
bool all; 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); st_select_lex *select_lex, bool all);
// only ALL subquery has upper not // only ALL subquery has upper not
......
...@@ -1797,9 +1797,9 @@ void Item_char_typecast::print(String *str) ...@@ -1797,9 +1797,9 @@ void Item_char_typecast::print(String *str)
{ {
str->append('('); str->append('(');
char buffer[20]; char buffer[20];
// latin1 is good enough for numbers // my_charset_bin is good enough for numbers
String st(buffer, sizeof(buffer), &my_charset_latin1); String st(buffer, sizeof(buffer), &my_charset_bin);
st.set((ulonglong)cast_length, &my_charset_latin1); st.set((ulonglong)cast_length, &my_charset_bin);
str->append(st); str->append(st);
str->append(')'); str->append(')');
} }
......
...@@ -338,7 +338,7 @@ inline THD *_current_thd(void) ...@@ -338,7 +338,7 @@ inline THD *_current_thd(void)
#include "protocol.h" #include "protocol.h"
#include "sql_udf.h" #include "sql_udf.h"
#include "item.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 "sql_class.h"
#include "opt_range.h" #include "opt_range.h"
...@@ -770,6 +770,12 @@ extern const char *first_keyword, *my_localhost, *delayed_user, *binary_keyword; ...@@ -770,6 +770,12 @@ extern const char *first_keyword, *my_localhost, *delayed_user, *binary_keyword;
extern const char **errmesg; /* Error messages */ extern const char **errmesg; /* Error messages */
extern const char *myisam_recover_options_str; extern const char *myisam_recover_options_str;
extern const char *in_left_expr_name, *in_additional_cond; 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 uchar *days_in_month;
extern char language[LIBLEN],reg_ext[FN_EXTLEN]; extern char language[LIBLEN],reg_ext[FN_EXTLEN];
extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN]; extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
...@@ -1059,12 +1065,12 @@ inline void table_case_convert(char * name, uint length) ...@@ -1059,12 +1065,12 @@ inline void table_case_convert(char * name, uint length)
my_casedn(files_charset_info, name, length); my_casedn(files_charset_info, name, length);
} }
compare_func_creator comp_eq_creator(bool invert); Comp_creator *comp_eq_creator(bool invert);
compare_func_creator comp_ge_creator(bool invert); Comp_creator *comp_ge_creator(bool invert);
compare_func_creator comp_gt_creator(bool invert); Comp_creator *comp_gt_creator(bool invert);
compare_func_creator comp_le_creator(bool invert); Comp_creator *comp_le_creator(bool invert);
compare_func_creator comp_lt_creator(bool invert); Comp_creator *comp_lt_creator(bool invert);
compare_func_creator comp_ne_creator(bool invert); Comp_creator *comp_ne_creator(bool invert);
Item * all_any_subquery_creator(Item *left_expr, Item * all_any_subquery_creator(Item *left_expr,
chooser_compare_func_creator cmp, chooser_compare_func_creator cmp,
......
...@@ -335,6 +335,14 @@ const char *sql_mode_str="OFF"; ...@@ -335,6 +335,14 @@ const char *sql_mode_str="OFF";
const char *in_left_expr_name= "<left expr>"; const char *in_left_expr_name= "<left expr>";
/* name of additional condition */ /* name of additional condition */
const char *in_additional_cond= "<IN COND>"; 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; FILE *bootstrap_file;
......
...@@ -4636,39 +4636,39 @@ bool check_simple_select() ...@@ -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;
} }
......
...@@ -680,3 +680,35 @@ outp: ...@@ -680,3 +680,35 @@ outp:
} }
return (uint32) (to - to_start); 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);
}
}
}
...@@ -289,4 +289,5 @@ public: ...@@ -289,4 +289,5 @@ public:
str_length+= arg_length; str_length+= arg_length;
return FALSE; return FALSE;
} }
void print(String *print);
}; };
...@@ -2304,15 +2304,22 @@ expr_expr: ...@@ -2304,15 +2304,22 @@ expr_expr:
| expr OR expr { $$= new Item_cond_or($1,$3); } | expr OR expr { $$= new Item_cond_or($1,$3); }
| expr XOR expr { $$= new Item_cond_xor($1,$3); } | expr XOR expr { $$= new Item_cond_xor($1,$3); }
| expr AND expr { $$= new Item_cond_and($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 SOUNDS_SYM LIKE expr
| 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));} $$= 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 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 NULL_SYM { $$= new Item_func_isnull($1); }
| expr IS NOT NULL_SYM { $$= new Item_func_isnotnull($1); } | expr IS NOT NULL_SYM { $$= new Item_func_isnotnull($1); }
| expr EQUAL_SYM expr { $$= new Item_func_equal($1,$3); } | 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 | expr comp_op all_or_any in_subselect %prec EQ
{ {
$$= all_any_subquery_creator($1, $2, $3, $4); $$= all_any_subquery_creator($1, $2, $3, $4);
...@@ -2345,15 +2352,22 @@ no_in_expr: ...@@ -2345,15 +2352,22 @@ no_in_expr:
| no_in_expr OR expr { $$= new Item_cond_or($1,$3); } | 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 XOR expr { $$= new Item_cond_xor($1,$3); }
| no_in_expr AND expr { $$= new Item_cond_and($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 SOUNDS_SYM LIKE expr
| 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)); } $$= 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 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 NULL_SYM { $$= new Item_func_isnull($1); }
| no_in_expr IS NOT NULL_SYM { $$= new Item_func_isnotnull($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 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 | no_in_expr comp_op all_or_any in_subselect %prec EQ
{ {
all_any_subquery_creator($1, $2, $3, $4); all_any_subquery_creator($1, $2, $3, $4);
...@@ -2395,15 +2409,22 @@ no_and_expr: ...@@ -2395,15 +2409,22 @@ no_and_expr:
| no_and_expr OR_OR_CONCAT expr { $$= or_or_concat(YYTHD, $1,$3); } | 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 OR expr { $$= new Item_cond_or($1,$3); }
| no_and_expr XOR expr { $$= new Item_cond_xor($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 SOUNDS_SYM LIKE expr
| 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)); } $$= 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 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 NULL_SYM { $$= new Item_func_isnull($1); }
| no_and_expr IS NOT NULL_SYM { $$= new Item_func_isnotnull($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 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 | no_and_expr comp_op all_or_any in_subselect %prec EQ
{ {
all_any_subquery_creator($1, $2, $3, $4); all_any_subquery_creator($1, $2, $3, $4);
......
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