diff options
author | Alexander Barkov <bar@mariadb.org> | 2014-09-01 20:57:32 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2014-09-01 20:57:32 +0400 |
commit | 1427e1db99ac44dedbc78e8655742a8ed9bfd755 (patch) | |
tree | a848c06ceed3a3a7a69e6ce159f92d2c3f96c5f0 /sql/item_xmlfunc.cc | |
parent | 18b307a7d23fd59b4a831e3e95207e2e34f56b6e (diff) | |
download | mariadb-git-1427e1db99ac44dedbc78e8655742a8ed9bfd755.tar.gz |
MDEV-6661 PI() does not work well in UCS2/UTF16/UTF32 context
MDEV-6666 Malformed result for CONCAT(utf8_column, binary_string)
Item_static_string_func::safe_charset_converter() and
Item_hex_string::safe_charset_converter() did not
handle character sets with mbminlen>1 properly, as well as
did not handle conversion from binary to multi-byte well.
Introducing Item::const_charset_converter(), to reuse it in a number
of Item_*::safe_charset_converter().
Diffstat (limited to 'sql/item_xmlfunc.cc')
-rw-r--r-- | sql/item_xmlfunc.cc | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 759b929ff82..932f4245c27 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -532,6 +532,32 @@ public: }; +/** + A string whose value may be changed during execution. +*/ +class Item_string_xml_non_const: public Item_string +{ +public: + Item_string_xml_non_const(const char *str, uint length, CHARSET_INFO *cs) + :Item_string(str, length, cs) + { } + bool const_item() const { return false ; } + bool basic_const_item() const { return false; } + void set_value(const char *str, uint length, CHARSET_INFO *cs) + { + str_value.set(str, length, cs); + } + Item *safe_charset_converter(CHARSET_INFO *tocs) + { + /* + Item_string::safe_charset_converter() does not accept non-constants. + Note, conversion is not really needed here anyway. + */ + return this; + } +}; + + class Item_nodeset_to_const_comparator :public Item_bool_func { String *pxml; @@ -550,7 +576,8 @@ public: longlong val_int() { Item_func *comp= (Item_func*)args[1]; - Item_string *fake= (Item_string*)(comp->arguments()[0]); + Item_string_xml_non_const *fake= + (Item_string_xml_non_const*)(comp->arguments()[0]); String *res= args[0]->val_nodeset(&tmp_nodeset); MY_XPATH_FLT *fltbeg= (MY_XPATH_FLT*) res->ptr(); MY_XPATH_FLT *fltend= (MY_XPATH_FLT*) (res->ptr() + res->length()); @@ -568,8 +595,8 @@ public: if ((node->parent == flt->num) && (node->type == MY_XML_NODE_TEXT)) { - fake->str_value.set(node->beg, node->end - node->beg, - collation.collation); + fake->set_value(node->beg, node->end - node->beg, + collation.collation); if (args[1]->val_int()) return 1; } @@ -956,14 +983,12 @@ static Item *create_comparator(MY_XPATH *xpath, { /* Compare a node set to a scalar value. - We just create a fake Item_string() argument, + We just create a fake Item_string_xml_non_const() argument, which will be filled to the partular value in a loop through all of the nodes in the node set. */ - Item_string *fake= new Item_string("", 0, xpath->cs); - /* Don't cache fake because its value will be changed during comparison.*/ - fake->set_used_tables(RAND_TABLE_BIT); + Item_string *fake= new Item_string_xml_non_const("", 0, xpath->cs); Item_nodeset_func *nodeset; Item *scalar, *comp; if (a->type() == Item::XPATH_NODESET) |