maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #10089
Please review MDEV-11292 Item_func_sp::fix_length_and_dec() does not set collation derivation properly
Hello Alexey,
Please review a patch for MDEV-11292 (for 10.3).
Thanks.
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index acd3d74..f02b66c 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -3621,51 +3621,13 @@ String *Item_func_weight_string::val_str(String *str)
}
-String *Item_func_hex::val_str_ascii(String *str)
+String *Item_func_hex::val_str_ascii_from_int(String *str, ulonglong num)
{
- String *res;
- DBUG_ASSERT(fixed == 1);
- if (args[0]->result_type() != STRING_RESULT)
- {
- ulonglong dec;
- char ans[65],*ptr;
- /* Return hex of unsigned longlong value */
- if (args[0]->result_type() == REAL_RESULT ||
- args[0]->result_type() == DECIMAL_RESULT)
- {
- double val= args[0]->val_real();
- if ((val <= (double) LONGLONG_MIN) ||
- (val >= (double) (ulonglong) ULONGLONG_MAX))
- dec= ~(longlong) 0;
- else
- dec= (ulonglong) (val + (val > 0 ? 0.5 : -0.5));
- }
- else
- dec= (ulonglong) args[0]->val_int();
-
- if ((null_value= args[0]->null_value))
- return 0;
-
- if (!(ptr= longlong2str(dec, ans, 16)) ||
- str->copy(ans,(uint32) (ptr - ans),
- &my_charset_numeric))
- return make_empty_result(); // End of memory
- return str;
- }
-
- /* Convert given string to a hex string, character by character */
- res= args[0]->val_str(str);
- if (!res || tmp_value.alloc(res->length()*2+1))
- {
- null_value=1;
- return 0;
- }
- null_value=0;
- tmp_value.length(res->length()*2);
- tmp_value.set_charset(&my_charset_latin1);
-
- octet2hex((char*) tmp_value.ptr(), res->ptr(), res->length());
- return &tmp_value;
+ char ans[65], *ptr;
+ if (!(ptr= longlong2str(num, ans, 16)) ||
+ str->copy(ans, (uint32) (ptr - ans), &my_charset_numeric))
+ return make_empty_result(); // End of memory
+ return str;
}
/** Convert given hex string to a binary string. */
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 25b63eb..9719879 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -913,17 +913,24 @@ class Item_func_conv :public Item_str_func
class Item_func_hex :public Item_str_ascii_func
{
+protected:
String tmp_value;
+ String *val_str_ascii_from_int(String *, ulonglong);
+ const Type_handler *m_handler;
public:
Item_func_hex(THD *thd, Item *a):
- Item_str_ascii_func(thd, a) {}
+ Item_str_ascii_func(thd, a), m_handler(NULL) {}
const char *func_name() const { return "hex"; }
- String *val_str_ascii(String *);
+ String *val_str_ascii(String *str)
+ {
+ return m_handler->Item_func_hex_val_str_ascii(this, str);
+ }
void fix_length_and_dec()
{
collation.set(default_charset());
decimals=0;
fix_char_length(args[0]->max_length * 2);
+ m_handler= args[0]->type_handler();
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_hex>(thd, mem_root, this); }
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index a80417f..0f85a84 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -640,3 +640,99 @@ Field *Type_handler_set::make_conversion_table_field(TABLE *table,
metadata & 0x00ff/*pack_length()*/,
((const Field_enum*) target)->typelib, target->charset());
}
+
+
+/***********************************************************************/
+
+class Item_func_hex_int: public Item_func_hex
+{
+public:
+ String *val_str_ascii(String *str)
+ {
+ ulonglong dec= (ulonglong) args[0]->val_int();
+ if ((null_value= args[0]->null_value))
+ return 0;
+ return val_str_ascii_from_int(str, dec);
+ }
+};
+
+
+class Item_func_hex_real: public Item_func_hex
+{
+public:
+ String *val_str_ascii(String *str)
+ {
+ ulonglong dec;
+ double val= args[0]->val_real();
+ if ((null_value= args[0]->null_value))
+ return 0;
+ if ((val <= (double) LONGLONG_MIN) ||
+ (val >= (double) (ulonglong) ULONGLONG_MAX))
+ dec= ~(longlong) 0;
+ else
+ dec= (ulonglong) (val + (val > 0 ? 0.5 : -0.5));
+ return val_str_ascii_from_int(str, dec);
+ }
+};
+
+
+class Item_func_hex_str: public Item_func_hex
+{
+public:
+ String *val_str_ascii(String *str)
+ {
+ /* Convert given string to a hex string, character by character */
+ String *res= args[0]->val_str(str);
+ if ((null_value= (!res || tmp_value.alloc(res->length() * 2 + 1))))
+ return 0;
+ tmp_value.length(res->length() * 2);
+ tmp_value.set_charset(&my_charset_latin1);
+ octet2hex((char*) tmp_value.ptr(), res->ptr(), res->length());
+ return &tmp_value;
+ }
+};
+
+
+String *
+Type_handler_real_result::Item_func_hex_val_str_ascii(Item_func_hex *item,
+ String *str) const
+{
+ return static_cast<Item_func_hex_real*>(item)->
+ Item_func_hex_real::val_str_ascii(str);
+}
+
+
+String *
+Type_handler_decimal_result::Item_func_hex_val_str_ascii(Item_func_hex *item,
+ String *str) const
+{
+ return static_cast<Item_func_hex_real*>(item)->
+ Item_func_hex_real::val_str_ascii(str);
+}
+
+
+String *
+Type_handler_int_result::Item_func_hex_val_str_ascii(Item_func_hex *item,
+ String *str) const
+{
+ return static_cast<Item_func_hex_int*>(item)->
+ Item_func_hex_int::val_str_ascii(str);
+}
+
+
+String *
+Type_handler_temporal_result::Item_func_hex_val_str_ascii(Item_func_hex *item,
+ String *str) const
+{
+ return static_cast<Item_func_hex_str*>(item)->
+ Item_func_hex_str::val_str_ascii(str);
+}
+
+
+String *
+Type_handler_string_result::Item_func_hex_val_str_ascii(Item_func_hex *item,
+ String *str) const
+{
+ return static_cast<Item_func_hex_str*>(item)->
+ Item_func_hex_str::val_str_ascii(str);
+}
diff --git a/sql/sql_type.h b/sql/sql_type.h
index 4b05a46..511a0fe 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -25,6 +25,7 @@
class Field;
class Item;
+class Item_func_hex;
class Type_std_attributes;
class Sort_param;
struct TABLE;
@@ -92,6 +93,9 @@ class Type_handler
virtual void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const= 0;
+
+ virtual String *Item_func_hex_val_str_ascii(Item_func_hex *item,
+ String *str) const= 0;
};
@@ -108,6 +112,8 @@ class Type_handler_real_result: public Type_handler
void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
+ String *Item_func_hex_val_str_ascii(Item_func_hex *item,
+ String *str) const;
};
@@ -123,6 +129,8 @@ class Type_handler_decimal_result: public Type_handler
void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
+ String *Item_func_hex_val_str_ascii(Item_func_hex *item,
+ String *str) const;
};
@@ -138,6 +146,8 @@ class Type_handler_int_result: public Type_handler
void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
+ String *Item_func_hex_val_str_ascii(Item_func_hex *item,
+ String *str) const;
};
@@ -152,6 +162,8 @@ class Type_handler_temporal_result: public Type_handler
void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
+ String *Item_func_hex_val_str_ascii(Item_func_hex *item,
+ String *str) const;
};
@@ -169,6 +181,8 @@ class Type_handler_string_result: public Type_handler
void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
+ String *Item_func_hex_val_str_ascii(Item_func_hex *item,
+ String *str) const;
};
Follow ups