diff options
-rw-r--r-- | mysql-test/r/func_str.result | 2 | ||||
-rw-r--r-- | sql/item.cc | 45 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 30 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 70 | ||||
-rw-r--r-- | sql/item_func.cc | 30 | ||||
-rw-r--r-- | sql/item_func.h | 2 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 10 | ||||
-rw-r--r-- | sql/item_subselect.cc | 96 | ||||
-rw-r--r-- | sql/item_subselect.h | 8 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 6 | ||||
-rw-r--r-- | sql/mysql_priv.h | 20 | ||||
-rw-r--r-- | sql/mysqld.cc | 8 | ||||
-rw-r--r-- | sql/sql_parse.cc | 24 | ||||
-rw-r--r-- | sql/sql_string.cc | 32 | ||||
-rw-r--r-- | sql/sql_string.h | 1 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 51 |
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 *)<_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 *)>_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 *)>_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 *)<_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); |