From 08de2540acc6a9e1aa24f26a18ac467ffc8284fd Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 26 Sep 2019 11:06:54 +0400 Subject: [PATCH] MDEV-20674 Reuse val_native() in ExtractValue() and UpdateXML() --- sql/item.h | 1 - sql/item_xmlfunc.cc | 250 ++++++++++++++++++-------------------------- sql/item_xmlfunc.h | 40 ++++++- 3 files changed, 141 insertions(+), 150 deletions(-) diff --git a/sql/item.h b/sql/item.h index f26ca6493d0..022a14585c3 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1467,7 +1467,6 @@ public: { return type_handler()->Item_val_bool(this); } - virtual String *val_raw(String*) { return 0; } bool eval_const_cond() { diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index d320b51879a..c8224157e0f 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -71,15 +71,6 @@ typedef struct my_xpath_lex_st } MY_XPATH_LEX; -/* Structure to store nodesets */ -typedef struct my_xpath_flt_st -{ - uint num; /* absolute position in MY_XML_NODE array */ - uint pos; /* relative position in context */ - uint size; /* context size */ -} MY_XPATH_FLT; - - /* XPath function creator */ typedef struct my_xpath_function_names_st { @@ -105,50 +96,13 @@ typedef struct my_xpath_st Item *item; /* current expression */ Item *context; /* last scanned context */ Item *rootelement; /* The root element */ - String *context_cache; /* last context provider */ + Native *context_cache; /* last context provider */ String *pxml; /* Parsed XML, an array of MY_XML_NODE */ CHARSET_INFO *cs; /* character set/collation string comparison */ int error; } MY_XPATH; -/* Dynamic array of MY_XPATH_FLT */ -class XPathFilter :public String -{ -public: - XPathFilter() :String() {} - inline bool append_element(MY_XPATH_FLT *flt) - { - String *str= this; - return str->append((const char*)flt, (uint32) sizeof(MY_XPATH_FLT)); - } - inline bool append_element(uint32 num, uint32 pos) - { - MY_XPATH_FLT add; - add.num= num; - add.pos= pos; - add.size= 0; - return append_element(&add); - } - inline bool append_element(uint32 num, uint32 pos, uint32 size) - { - MY_XPATH_FLT add; - add.num= num; - add.pos= pos; - add.size= size; - return append_element(&add); - } - inline MY_XPATH_FLT *element(uint i) - { - return (MY_XPATH_FLT*) (ptr() + i * sizeof(MY_XPATH_FLT)); - } - inline uint32 numelements() - { - return length() / sizeof(MY_XPATH_FLT); - } -}; - - static Type_handler_long_blob type_handler_xpath_nodeset; @@ -158,13 +112,13 @@ static Type_handler_long_blob type_handler_xpath_nodeset; class Item_nodeset_func :public Item_str_func { protected: - String tmp_value, tmp2_value; + NativeNodesetBuffer tmp_native_value, tmp2_native_value; MY_XPATH_FLT *fltbeg, *fltend; MY_XML_NODE *nodebeg, *nodeend; uint numnodes; public: String *pxml; - String context_cache; + NativeNodesetBuffer context_cache; Item_nodeset_func(THD *thd, String *pxml_arg): Item_str_func(thd), pxml(pxml_arg) {} Item_nodeset_func(THD *thd, Item *a, String *pxml_arg): @@ -179,12 +133,12 @@ public: nodeend= (MY_XML_NODE*) (pxml->ptr() + pxml->length()); numnodes= (uint)(nodeend - nodebeg); } - void prepare(String *nodeset) + void prepare(THD *thd, Native *nodeset) { prepare_nodes(); - String *res= args[0]->val_raw(&tmp_value); - fltbeg= (MY_XPATH_FLT*) res->ptr(); - fltend= (MY_XPATH_FLT*) (res->ptr() + res->length()); + args[0]->val_native(thd, &tmp_native_value); + fltbeg= (MY_XPATH_FLT*) tmp_native_value.ptr(); + fltend= (MY_XPATH_FLT*) tmp_native_value.end(); nodeset->length(0); } const Type_handler *type_handler() const @@ -204,9 +158,9 @@ public: String *val_str(String *str) { prepare_nodes(); - String *res= val_raw(&tmp2_value); - fltbeg= (MY_XPATH_FLT*) res->ptr(); - fltend= (MY_XPATH_FLT*) (res->ptr() + res->length()); + val_native(current_thd, &tmp2_native_value); + fltbeg= (MY_XPATH_FLT*) tmp2_native_value.ptr(); + fltend= (MY_XPATH_FLT*) tmp2_native_value.end(); String active; active.alloc(numnodes); bzero((char*) active.ptr(), numnodes); @@ -235,7 +189,6 @@ public: } return str; } - enum Item_result result_type () const { return STRING_RESULT; } bool fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; @@ -261,7 +214,7 @@ public: Item_nodeset_func_rootelement(THD *thd, String *pxml): Item_nodeset_func(thd, pxml) {} const char *func_name() const { return "xpath_rootelement"; } - String *val_raw(String *nodeset); + bool val_native(THD *thd, Native *nodeset); Item *get_copy(THD *thd) { return get_item_copy(thd, this); } }; @@ -274,7 +227,7 @@ public: Item_nodeset_func_union(THD *thd, Item *a, Item *b, String *pxml): Item_nodeset_func(thd, a, b, pxml) {} const char *func_name() const { return "xpath_union"; } - String *val_raw(String *nodeset); + bool val_native(THD *thd, Native *nodeset); Item *get_copy(THD *thd) { return get_item_copy(thd, this); } }; @@ -308,7 +261,7 @@ public: String *pxml): Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {} const char *func_name() const { return "xpath_selfbyname"; } - String *val_raw(String *nodeset); + bool val_native(THD *thd, Native *nodeset); Item *get_copy(THD *thd) { return get_item_copy(thd, this); } }; @@ -322,7 +275,7 @@ public: String *pxml): Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {} const char *func_name() const { return "xpath_childbyname"; } - String *val_raw(String *nodeset); + bool val_native(THD *thd, Native *nodeset); Item *get_copy(THD *thd) { return get_item_copy(thd, this); } }; @@ -338,7 +291,7 @@ public: Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml), need_self(need_self_arg) {} const char *func_name() const { return "xpath_descendantbyname"; } - String *val_raw(String *nodeset); + bool val_native(THD *thd, Native *nodeset); Item *get_copy(THD *thd) { return get_item_copy(thd, this); } }; @@ -354,7 +307,7 @@ public: Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml), need_self(need_self_arg) {} const char *func_name() const { return "xpath_ancestorbyname"; } - String *val_raw(String *nodeset); + bool val_native(THD *thd, Native *nodeset); Item *get_copy(THD *thd) { return get_item_copy(thd, this); } }; @@ -368,7 +321,7 @@ public: String *pxml): Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {} const char *func_name() const { return "xpath_parentbyname"; } - String *val_raw(String *nodeset); + bool val_native(THD *thd, Native *nodeset); Item *get_copy(THD *thd) { return get_item_copy(thd, this); } }; @@ -382,7 +335,7 @@ public: uint l_arg, String *pxml): Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {} const char *func_name() const { return "xpath_attributebyname"; } - String *val_raw(String *nodeset); + bool val_native(THD *thd, Native *nodeset); Item *get_copy(THD *thd) { return get_item_copy(thd, this); } }; @@ -399,7 +352,7 @@ public: Item_nodeset_func_predicate(THD *thd, Item *a, Item *b, String *pxml): Item_nodeset_func(thd, a, b, pxml) {} const char *func_name() const { return "xpath_predicate"; } - String *val_raw(String *nodeset); + bool val_native(THD *thd, Native *nodeset); Item *get_copy(THD *thd) { return get_item_copy(thd, this); } }; @@ -412,7 +365,7 @@ public: Item_nodeset_func_elementbyindex(THD *thd, Item *a, Item *b, String *pxml): Item_nodeset_func(thd, a, b, pxml) { } const char *func_name() const { return "xpath_elementbyindex"; } - String *val_raw(String *nodeset); + bool val_native(THD *thd, Native *nodeset); Item *get_copy(THD *thd) { return get_item_copy(thd, this); } }; @@ -427,7 +380,7 @@ public: class Item_xpath_cast_bool :public Item_bool_func { String *pxml; - String tmp_value; + NativeNodesetBuffer tmp_native_value; public: Item_xpath_cast_bool(THD *thd, Item *a, String *pxml_arg): Item_bool_func(thd, a), pxml(pxml_arg) {} @@ -436,8 +389,8 @@ public: { if (args[0]->fixed_type_handler() == &type_handler_xpath_nodeset) { - String *flt= args[0]->val_raw(&tmp_value); - return flt->length() == sizeof(MY_XPATH_FLT) ? 1 : 0; + args[0]->val_native(current_thd, &tmp_native_value); + return tmp_native_value.elements() == 1 ? 1 : 0; } return args[0]->val_real() ? 1 : 0; } @@ -466,11 +419,13 @@ public: class Item_nodeset_context_cache :public Item_nodeset_func { public: - String *string_cache; - Item_nodeset_context_cache(THD *thd, String *str_arg, String *pxml): - Item_nodeset_func(thd, pxml), string_cache(str_arg) { } - String *val_raw(String *res) - { return string_cache; } + Native *native_cache; + Item_nodeset_context_cache(THD *thd, Native *native_arg, String *pxml): + Item_nodeset_func(thd, pxml), native_cache(native_arg) { } + bool val_native(THD *thd, Native *nodeset) + { + return nodeset->copy(*native_cache); + } bool fix_length_and_dec() { max_length= MAX_BLOB_WIDTH;; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy(thd, this); } @@ -480,7 +435,7 @@ public: class Item_func_xpath_position :public Item_long_func { String *pxml; - String tmp_value; + NativeNodesetBuffer tmp_native_value; public: Item_func_xpath_position(THD *thd, Item *a, String *p): Item_long_func(thd, a), pxml(p) {} @@ -488,9 +443,9 @@ public: bool fix_length_and_dec() { max_length=10; return FALSE; } longlong val_int() { - String *flt= args[0]->val_raw(&tmp_value); - if (flt->length() == sizeof(MY_XPATH_FLT)) - return ((MY_XPATH_FLT*)flt->ptr())->pos + 1; + args[0]->val_native(current_thd, &tmp_native_value); + if (tmp_native_value.elements() == 1) + return tmp_native_value.element(0).pos + 1; return 0; } Item *get_copy(THD *thd) @@ -501,7 +456,7 @@ public: class Item_func_xpath_count :public Item_long_func { String *pxml; - String tmp_value; + NativeNodesetBuffer tmp_native_value; public: Item_func_xpath_count(THD *thd, Item *a, String *p): Item_long_func(thd, a), pxml(p) {} @@ -510,11 +465,11 @@ public: longlong val_int() { uint predicate_supplied_context_size; - String *res= args[0]->val_raw(&tmp_value); - if (res->length() == sizeof(MY_XPATH_FLT) && - (predicate_supplied_context_size= ((MY_XPATH_FLT*)res->ptr())->size)) + args[0]->val_native(current_thd, &tmp_native_value); + if (tmp_native_value.elements() == 1 && + (predicate_supplied_context_size= tmp_native_value.element(0).size)) return predicate_supplied_context_size; - return res->length() / sizeof(MY_XPATH_FLT); + return tmp_native_value.elements(); } Item *get_copy(THD *thd) { return get_item_copy(thd, this); } @@ -524,7 +479,7 @@ public: class Item_func_xpath_sum :public Item_real_func { String *pxml; - String tmp_value; + NativeNodesetBuffer tmp_native_value; public: Item_func_xpath_sum(THD *thd, Item *a, String *p): Item_real_func(thd, a), pxml(p) {} @@ -533,9 +488,9 @@ public: double val_real() { double sum= 0; - String *res= args[0]->val_raw(&tmp_value); - MY_XPATH_FLT *fltbeg= (MY_XPATH_FLT*) res->ptr(); - MY_XPATH_FLT *fltend= (MY_XPATH_FLT*) (res->ptr() + res->length()); + args[0]->val_native(current_thd, &tmp_native_value); + MY_XPATH_FLT *fltbeg= (MY_XPATH_FLT*) tmp_native_value.ptr(); + MY_XPATH_FLT *fltend= (MY_XPATH_FLT*) tmp_native_value.end(); uint numnodes= pxml->length() / sizeof(MY_XML_NODE); MY_XML_NODE *nodebeg= (MY_XML_NODE*) pxml->ptr(); @@ -596,7 +551,7 @@ public: class Item_nodeset_to_const_comparator :public Item_bool_func { String *pxml; - String tmp_nodeset; + NativeNodesetBuffer tmp_nodeset; public: Item_nodeset_to_const_comparator(THD *thd, Item *nodeset, Item *cmpfunc, String *p): @@ -617,9 +572,9 @@ public: Item_func *comp= (Item_func*)args[1]; Item_string_xml_non_const *fake= (Item_string_xml_non_const*)(comp->arguments()[0]); - String *res= args[0]->val_raw(&tmp_nodeset); - MY_XPATH_FLT *fltbeg= (MY_XPATH_FLT*) res->ptr(); - MY_XPATH_FLT *fltend= (MY_XPATH_FLT*) (res->ptr() + res->length()); + args[0]->val_native(current_thd, &tmp_nodeset); + MY_XPATH_FLT *fltbeg= (MY_XPATH_FLT*) tmp_nodeset.ptr(); + MY_XPATH_FLT *fltend= (MY_XPATH_FLT*) tmp_nodeset.end(); MY_XML_NODE *nodebeg= (MY_XML_NODE*) pxml->ptr(); uint numnodes= pxml->length() / sizeof(MY_XML_NODE); @@ -648,32 +603,32 @@ public: }; -String *Item_nodeset_func_rootelement::val_raw(String *nodeset) +bool Item_nodeset_func_rootelement::val_native(THD *thd, Native *nodeset) { nodeset->length(0); - ((XPathFilter*)nodeset)->append_element(0, 0); - return nodeset; + return MY_XPATH_FLT(0, 0).append_to(nodeset); } -String * Item_nodeset_func_union::val_raw(String *nodeset) +bool Item_nodeset_func_union::val_native(THD *thd, Native *nodeset) { uint num_nodes= pxml->length() / sizeof(MY_XML_NODE); - String set0, *s0= args[0]->val_raw(&set0); - String set1, *s1= args[1]->val_raw(&set1); + NativeNodesetBuffer set0, set1; + args[0]->val_native(thd, &set0); + args[1]->val_native(thd, &set1); String both_str; both_str.alloc(num_nodes); char *both= (char*) both_str.ptr(); bzero((void*)both, num_nodes); MY_XPATH_FLT *flt; - fltbeg= (MY_XPATH_FLT*) s0->ptr(); - fltend= (MY_XPATH_FLT*) (s0->ptr() + s0->length()); + fltbeg= (MY_XPATH_FLT*) set0.ptr(); + fltend= (MY_XPATH_FLT*) set0.end(); for (flt= fltbeg; flt < fltend; flt++) both[flt->num]= 1; - fltbeg= (MY_XPATH_FLT*) s1->ptr(); - fltend= (MY_XPATH_FLT*) (s1->ptr() + s1->length()); + fltbeg= (MY_XPATH_FLT*) set1.ptr(); + fltend= (MY_XPATH_FLT*) set1.end(); for (flt= fltbeg; flt < fltend; flt++) both[flt->num]= 1; @@ -681,29 +636,29 @@ String * Item_nodeset_func_union::val_raw(String *nodeset) for (uint i= 0, pos= 0; i < num_nodes; i++) { if (both[i]) - ((XPathFilter*)nodeset)->append_element(i, pos++); + MY_XPATH_FLT(i, pos++).append_to(nodeset); } - return nodeset; + return false; } -String *Item_nodeset_func_selfbyname::val_raw(String *nodeset) +bool Item_nodeset_func_selfbyname::val_native(THD *thd, Native *nodeset) { - prepare(nodeset); + prepare(thd, nodeset); for (MY_XPATH_FLT *flt= fltbeg; flt < fltend; flt++) { uint pos= 0; MY_XML_NODE *self= &nodebeg[flt->num]; if (validname(self)) - ((XPathFilter*)nodeset)->append_element(flt->num,pos++); + MY_XPATH_FLT(flt->num, pos++).append_to(nodeset); } - return nodeset; + return false; } -String *Item_nodeset_func_childbyname::val_raw(String *nodeset) +bool Item_nodeset_func_childbyname::val_native(THD *thd, Native *nodeset) { - prepare(nodeset); + prepare(thd, nodeset); for (MY_XPATH_FLT *flt= fltbeg; flt < fltend; flt++) { MY_XML_NODE *self= &nodebeg[flt->num]; @@ -715,40 +670,40 @@ String *Item_nodeset_func_childbyname::val_raw(String *nodeset) if ((node->parent == flt->num) && (node->type == MY_XML_NODE_TAG) && validname(node)) - ((XPathFilter*)nodeset)->append_element(j, pos++); + MY_XPATH_FLT(j, pos++).append_to(nodeset); } } - return nodeset; + return false; } -String *Item_nodeset_func_descendantbyname::val_raw(String *nodeset) +bool Item_nodeset_func_descendantbyname::val_native(THD *thd, Native *nodeset) { - prepare(nodeset); + prepare(thd, nodeset); for (MY_XPATH_FLT *flt= fltbeg; flt < fltend; flt++) { uint pos= 0; MY_XML_NODE *self= &nodebeg[flt->num]; if (need_self && validname(self)) - ((XPathFilter*)nodeset)->append_element(flt->num,pos++); + MY_XPATH_FLT(flt->num, pos++).append_to(nodeset); for (uint j= flt->num + 1 ; j < numnodes ; j++) { MY_XML_NODE *node= &nodebeg[j]; if (node->level <= self->level) break; if ((node->type == MY_XML_NODE_TAG) && validname(node)) - ((XPathFilter*)nodeset)->append_element(j,pos++); + MY_XPATH_FLT(j, pos++).append_to(nodeset); } } - return nodeset; + return false; } -String *Item_nodeset_func_ancestorbyname::val_raw(String *nodeset) +bool Item_nodeset_func_ancestorbyname::val_native(THD *thd, Native *nodeset) { char *active; String active_str; - prepare(nodeset); + prepare(thd, nodeset); active_str.alloc(numnodes); active= (char*) active_str.ptr(); bzero((void*)active, numnodes); @@ -780,17 +735,17 @@ String *Item_nodeset_func_ancestorbyname::val_raw(String *nodeset) for (uint j= 0; j < numnodes ; j++) { if (active[j]) - ((XPathFilter*)nodeset)->append_element(j, --pos); + MY_XPATH_FLT(j, --pos).append_to(nodeset); } - return nodeset; + return false; } -String *Item_nodeset_func_parentbyname::val_raw(String *nodeset) +bool Item_nodeset_func_parentbyname::val_native(THD *thd, Native *nodeset) { char *active; String active_str; - prepare(nodeset); + prepare(thd, nodeset); active_str.alloc(numnodes); active= (char*) active_str.ptr(); bzero((void*)active, numnodes); @@ -803,15 +758,15 @@ String *Item_nodeset_func_parentbyname::val_raw(String *nodeset) for (uint j= 0, pos= 0; j < numnodes ; j++) { if (active[j]) - ((XPathFilter*)nodeset)->append_element(j, pos++); + MY_XPATH_FLT(j, pos++).append_to(nodeset); } - return nodeset; + return false; } -String *Item_nodeset_func_attributebyname::val_raw(String *nodeset) +bool Item_nodeset_func_attributebyname::val_native(THD *thd, Native *nodeset) { - prepare(nodeset); + prepare(thd, nodeset); for (MY_XPATH_FLT *flt= fltbeg; flt < fltend; flt++) { MY_XML_NODE *self= &nodebeg[flt->num]; @@ -823,52 +778,50 @@ String *Item_nodeset_func_attributebyname::val_raw(String *nodeset) if ((node->parent == flt->num) && (node->type == MY_XML_NODE_ATTR) && validname(node)) - ((XPathFilter*)nodeset)->append_element(j, pos++); + MY_XPATH_FLT(j, pos++).append_to(nodeset); } } - return nodeset; + return false; } -String *Item_nodeset_func_predicate::val_raw(String *str) +bool Item_nodeset_func_predicate::val_native(THD *thd, Native *str) { Item_nodeset_func *nodeset_func= (Item_nodeset_func*) args[0]; Item_func *comp_func= (Item_func*)args[1]; uint pos= 0, size; - prepare(str); + prepare(thd, str); size= (uint)(fltend - fltbeg); for (MY_XPATH_FLT *flt= fltbeg; flt < fltend; flt++) { nodeset_func->context_cache.length(0); - ((XPathFilter*)(&nodeset_func->context_cache))->append_element(flt->num, - flt->pos, - size); + MY_XPATH_FLT(flt->num, flt->pos, size). + append_to(&nodeset_func->context_cache); if (comp_func->val_int()) - ((XPathFilter*)str)->append_element(flt->num, pos++); + MY_XPATH_FLT(flt->num, pos++).append_to(str); } - return str; + return false; } -String *Item_nodeset_func_elementbyindex::val_raw(String *nodeset) +bool Item_nodeset_func_elementbyindex::val_native(THD *thd, Native *nodeset) { Item_nodeset_func *nodeset_func= (Item_nodeset_func*) args[0]; - prepare(nodeset); + prepare(thd, nodeset); MY_XPATH_FLT *flt; uint pos, size= (uint)(fltend - fltbeg); for (pos= 0, flt= fltbeg; flt < fltend; flt++) { nodeset_func->context_cache.length(0); - ((XPathFilter*)(&nodeset_func->context_cache))->append_element(flt->num, - flt->pos, - size); + MY_XPATH_FLT(flt->num, flt->pos, size). + append_to(&nodeset_func->context_cache); int index= (int) (args[1]->val_int()) - 1; if (index >= 0 && (flt->pos == (uint) index || (args[1]->type_handler()->is_bool_type()))) - ((XPathFilter*)nodeset)->append_element(flt->num, pos++); + MY_XPATH_FLT(flt->num, pos++).append_to(nodeset); } - return nodeset; + return false; } @@ -1793,7 +1746,7 @@ my_xpath_parse_AxisSpecifier_NodeTest_opt_Predicate_list(MY_XPATH *xpath) while (my_xpath_parse_term(xpath, MY_XPATH_LEX_LB)) { Item *prev_context= xpath->context; - String *context_cache; + Native *context_cache; context_cache= &((Item_nodeset_func*)xpath->context)->context_cache; xpath->context= new (xpath->thd->mem_root) Item_nodeset_context_cache(xpath->thd, context_cache, xpath->pxml); @@ -3070,19 +3023,20 @@ bool Item_func_xml_update::collect_result(String *str, String *Item_func_xml_update::val_str(String *str) { - String *nodeset, *rep; + String *rep; null_value= 0; if (!nodeset_func || get_xml(&xml) || !(rep= args[2]->val_str(&tmp_value3)) || - !(nodeset= nodeset_func->val_raw(&tmp_value2))) + nodeset_func->type_handler() != &type_handler_xpath_nodeset || + nodeset_func->val_native(current_thd, &tmp_native_value2)) { null_value= 1; return 0; } - MY_XPATH_FLT *fltbeg= (MY_XPATH_FLT*) nodeset->ptr(); - MY_XPATH_FLT *fltend= (MY_XPATH_FLT*) (nodeset->ptr() + nodeset->length()); + MY_XPATH_FLT *fltbeg= (MY_XPATH_FLT*) tmp_native_value2.ptr(); + MY_XPATH_FLT *fltend= (MY_XPATH_FLT*) tmp_native_value2.end(); /* Allow replacing of one tag only */ if (fltend - fltbeg != 1) diff --git a/sql/item_xmlfunc.h b/sql/item_xmlfunc.h index ce34697d9bd..806739d1139 100644 --- a/sql/item_xmlfunc.h +++ b/sql/item_xmlfunc.h @@ -2,6 +2,7 @@ #define ITEM_XMLFUNC_INCLUDED /* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2009, 2019, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,6 +24,42 @@ typedef struct my_xml_node_st MY_XML_NODE; +/* Structure to store nodeset elements */ +class MY_XPATH_FLT +{ +public: + uint num; // Absolute position in MY_XML_NODE array + uint pos; // Relative position in context + uint size; // Context size +public: + MY_XPATH_FLT(uint32 num_arg, uint32 pos_arg) + :num(num_arg), pos(pos_arg), size(0) + { } + MY_XPATH_FLT(uint32 num_arg, uint32 pos_arg, uint32 size_arg) + :num(num_arg), pos(pos_arg), size(size_arg) + { } + bool append_to(Native *to) const + { + return to->append((const char*) this, (uint32) sizeof(*this)); + } +}; + + +class NativeNodesetBuffer: public NativeBuffer<16*sizeof(MY_XPATH_FLT)> +{ +public: + const MY_XPATH_FLT &element(uint i) const + { + const MY_XPATH_FLT *p= (MY_XPATH_FLT*) (ptr() + i * sizeof(MY_XPATH_FLT)); + return *p; + } + uint32 elements() const + { + return length() / sizeof(MY_XPATH_FLT); + } +}; + + class Item_xml_str_func: public Item_str_func { protected: @@ -103,7 +140,8 @@ public: class Item_func_xml_update: public Item_xml_str_func { - String tmp_value2, tmp_value3; + NativeNodesetBuffer tmp_native_value2; + String tmp_value3; bool collect_result(String *str, const MY_XML_NODE *cut, const String *replace);