Commit 08de2540 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-20674 Reuse val_native() in ExtractValue() and UpdateXML()

parent a340af92
...@@ -1467,7 +1467,6 @@ class Item: public Value_source, ...@@ -1467,7 +1467,6 @@ class Item: public Value_source,
{ {
return type_handler()->Item_val_bool(this); return type_handler()->Item_val_bool(this);
} }
virtual String *val_raw(String*) { return 0; }
bool eval_const_cond() bool eval_const_cond()
{ {
......
...@@ -71,15 +71,6 @@ typedef struct my_xpath_lex_st ...@@ -71,15 +71,6 @@ typedef struct my_xpath_lex_st
} MY_XPATH_LEX; } 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 */ /* XPath function creator */
typedef struct my_xpath_function_names_st typedef struct my_xpath_function_names_st
{ {
...@@ -105,50 +96,13 @@ typedef struct my_xpath_st ...@@ -105,50 +96,13 @@ typedef struct my_xpath_st
Item *item; /* current expression */ Item *item; /* current expression */
Item *context; /* last scanned context */ Item *context; /* last scanned context */
Item *rootelement; /* The root element */ 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 */ String *pxml; /* Parsed XML, an array of MY_XML_NODE */
CHARSET_INFO *cs; /* character set/collation string comparison */ CHARSET_INFO *cs; /* character set/collation string comparison */
int error; int error;
} MY_XPATH; } 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; static Type_handler_long_blob type_handler_xpath_nodeset;
...@@ -158,13 +112,13 @@ 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 class Item_nodeset_func :public Item_str_func
{ {
protected: protected:
String tmp_value, tmp2_value; NativeNodesetBuffer tmp_native_value, tmp2_native_value;
MY_XPATH_FLT *fltbeg, *fltend; MY_XPATH_FLT *fltbeg, *fltend;
MY_XML_NODE *nodebeg, *nodeend; MY_XML_NODE *nodebeg, *nodeend;
uint numnodes; uint numnodes;
public: public:
String *pxml; String *pxml;
String context_cache; NativeNodesetBuffer context_cache;
Item_nodeset_func(THD *thd, String *pxml_arg): Item_nodeset_func(THD *thd, String *pxml_arg):
Item_str_func(thd), pxml(pxml_arg) {} Item_str_func(thd), pxml(pxml_arg) {}
Item_nodeset_func(THD *thd, Item *a, String *pxml_arg): Item_nodeset_func(THD *thd, Item *a, String *pxml_arg):
...@@ -179,12 +133,12 @@ class Item_nodeset_func :public Item_str_func ...@@ -179,12 +133,12 @@ class Item_nodeset_func :public Item_str_func
nodeend= (MY_XML_NODE*) (pxml->ptr() + pxml->length()); nodeend= (MY_XML_NODE*) (pxml->ptr() + pxml->length());
numnodes= (uint)(nodeend - nodebeg); numnodes= (uint)(nodeend - nodebeg);
} }
void prepare(String *nodeset) void prepare(THD *thd, Native *nodeset)
{ {
prepare_nodes(); prepare_nodes();
String *res= args[0]->val_raw(&tmp_value); args[0]->val_native(thd, &tmp_native_value);
fltbeg= (MY_XPATH_FLT*) res->ptr(); fltbeg= (MY_XPATH_FLT*) tmp_native_value.ptr();
fltend= (MY_XPATH_FLT*) (res->ptr() + res->length()); fltend= (MY_XPATH_FLT*) tmp_native_value.end();
nodeset->length(0); nodeset->length(0);
} }
const Type_handler *type_handler() const const Type_handler *type_handler() const
...@@ -204,9 +158,9 @@ class Item_nodeset_func :public Item_str_func ...@@ -204,9 +158,9 @@ class Item_nodeset_func :public Item_str_func
String *val_str(String *str) String *val_str(String *str)
{ {
prepare_nodes(); prepare_nodes();
String *res= val_raw(&tmp2_value); val_native(current_thd, &tmp2_native_value);
fltbeg= (MY_XPATH_FLT*) res->ptr(); fltbeg= (MY_XPATH_FLT*) tmp2_native_value.ptr();
fltend= (MY_XPATH_FLT*) (res->ptr() + res->length()); fltend= (MY_XPATH_FLT*) tmp2_native_value.end();
String active; String active;
active.alloc(numnodes); active.alloc(numnodes);
bzero((char*) active.ptr(), numnodes); bzero((char*) active.ptr(), numnodes);
...@@ -235,7 +189,6 @@ class Item_nodeset_func :public Item_str_func ...@@ -235,7 +189,6 @@ class Item_nodeset_func :public Item_str_func
} }
return str; return str;
} }
enum Item_result result_type () const { return STRING_RESULT; }
bool fix_length_and_dec() bool fix_length_and_dec()
{ {
max_length= MAX_BLOB_WIDTH; max_length= MAX_BLOB_WIDTH;
...@@ -261,7 +214,7 @@ class Item_nodeset_func_rootelement :public Item_nodeset_func ...@@ -261,7 +214,7 @@ class Item_nodeset_func_rootelement :public Item_nodeset_func
Item_nodeset_func_rootelement(THD *thd, String *pxml): Item_nodeset_func_rootelement(THD *thd, String *pxml):
Item_nodeset_func(thd, pxml) {} Item_nodeset_func(thd, pxml) {}
const char *func_name() const { return "xpath_rootelement"; } 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) Item *get_copy(THD *thd)
{ return get_item_copy<Item_nodeset_func_rootelement>(thd, this); } { return get_item_copy<Item_nodeset_func_rootelement>(thd, this); }
}; };
...@@ -274,7 +227,7 @@ class Item_nodeset_func_union :public Item_nodeset_func ...@@ -274,7 +227,7 @@ class Item_nodeset_func_union :public Item_nodeset_func
Item_nodeset_func_union(THD *thd, Item *a, Item *b, String *pxml): Item_nodeset_func_union(THD *thd, Item *a, Item *b, String *pxml):
Item_nodeset_func(thd, a, b, pxml) {} Item_nodeset_func(thd, a, b, pxml) {}
const char *func_name() const { return "xpath_union"; } 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) Item *get_copy(THD *thd)
{ return get_item_copy<Item_nodeset_func_union>(thd, this); } { return get_item_copy<Item_nodeset_func_union>(thd, this); }
}; };
...@@ -308,7 +261,7 @@ class Item_nodeset_func_selfbyname: public Item_nodeset_func_axisbyname ...@@ -308,7 +261,7 @@ class Item_nodeset_func_selfbyname: public Item_nodeset_func_axisbyname
String *pxml): String *pxml):
Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {} Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {}
const char *func_name() const { return "xpath_selfbyname"; } 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) Item *get_copy(THD *thd)
{ return get_item_copy<Item_nodeset_func_selfbyname>(thd, this); } { return get_item_copy<Item_nodeset_func_selfbyname>(thd, this); }
}; };
...@@ -322,7 +275,7 @@ class Item_nodeset_func_childbyname: public Item_nodeset_func_axisbyname ...@@ -322,7 +275,7 @@ class Item_nodeset_func_childbyname: public Item_nodeset_func_axisbyname
String *pxml): String *pxml):
Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {} Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {}
const char *func_name() const { return "xpath_childbyname"; } 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) Item *get_copy(THD *thd)
{ return get_item_copy<Item_nodeset_func_childbyname>(thd, this); } { return get_item_copy<Item_nodeset_func_childbyname>(thd, this); }
}; };
...@@ -338,7 +291,7 @@ class Item_nodeset_func_descendantbyname: public Item_nodeset_func_axisbyname ...@@ -338,7 +291,7 @@ class Item_nodeset_func_descendantbyname: public Item_nodeset_func_axisbyname
Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml), Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml),
need_self(need_self_arg) {} need_self(need_self_arg) {}
const char *func_name() const { return "xpath_descendantbyname"; } 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) Item *get_copy(THD *thd)
{ return get_item_copy<Item_nodeset_func_descendantbyname>(thd, this); } { return get_item_copy<Item_nodeset_func_descendantbyname>(thd, this); }
}; };
...@@ -354,7 +307,7 @@ class Item_nodeset_func_ancestorbyname: public Item_nodeset_func_axisbyname ...@@ -354,7 +307,7 @@ class Item_nodeset_func_ancestorbyname: public Item_nodeset_func_axisbyname
Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml), Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml),
need_self(need_self_arg) {} need_self(need_self_arg) {}
const char *func_name() const { return "xpath_ancestorbyname"; } 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) Item *get_copy(THD *thd)
{ return get_item_copy<Item_nodeset_func_ancestorbyname>(thd, this); } { return get_item_copy<Item_nodeset_func_ancestorbyname>(thd, this); }
}; };
...@@ -368,7 +321,7 @@ class Item_nodeset_func_parentbyname: public Item_nodeset_func_axisbyname ...@@ -368,7 +321,7 @@ class Item_nodeset_func_parentbyname: public Item_nodeset_func_axisbyname
String *pxml): String *pxml):
Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {} Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {}
const char *func_name() const { return "xpath_parentbyname"; } 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) Item *get_copy(THD *thd)
{ return get_item_copy<Item_nodeset_func_parentbyname>(thd, this); } { return get_item_copy<Item_nodeset_func_parentbyname>(thd, this); }
}; };
...@@ -382,7 +335,7 @@ class Item_nodeset_func_attributebyname: public Item_nodeset_func_axisbyname ...@@ -382,7 +335,7 @@ class Item_nodeset_func_attributebyname: public Item_nodeset_func_axisbyname
uint l_arg, String *pxml): uint l_arg, String *pxml):
Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {} Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {}
const char *func_name() const { return "xpath_attributebyname"; } 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) Item *get_copy(THD *thd)
{ return get_item_copy<Item_nodeset_func_attributebyname>(thd, this); } { return get_item_copy<Item_nodeset_func_attributebyname>(thd, this); }
}; };
...@@ -399,7 +352,7 @@ class Item_nodeset_func_predicate :public Item_nodeset_func ...@@ -399,7 +352,7 @@ class Item_nodeset_func_predicate :public Item_nodeset_func
Item_nodeset_func_predicate(THD *thd, Item *a, Item *b, String *pxml): Item_nodeset_func_predicate(THD *thd, Item *a, Item *b, String *pxml):
Item_nodeset_func(thd, a, b, pxml) {} Item_nodeset_func(thd, a, b, pxml) {}
const char *func_name() const { return "xpath_predicate"; } 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) Item *get_copy(THD *thd)
{ return get_item_copy<Item_nodeset_func_predicate>(thd, this); } { return get_item_copy<Item_nodeset_func_predicate>(thd, this); }
}; };
...@@ -412,7 +365,7 @@ class Item_nodeset_func_elementbyindex :public Item_nodeset_func ...@@ -412,7 +365,7 @@ class Item_nodeset_func_elementbyindex :public Item_nodeset_func
Item_nodeset_func_elementbyindex(THD *thd, Item *a, Item *b, String *pxml): Item_nodeset_func_elementbyindex(THD *thd, Item *a, Item *b, String *pxml):
Item_nodeset_func(thd, a, b, pxml) { } Item_nodeset_func(thd, a, b, pxml) { }
const char *func_name() const { return "xpath_elementbyindex"; } 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) Item *get_copy(THD *thd)
{ return get_item_copy<Item_nodeset_func_elementbyindex>(thd, this); } { return get_item_copy<Item_nodeset_func_elementbyindex>(thd, this); }
}; };
...@@ -427,7 +380,7 @@ class Item_nodeset_func_elementbyindex :public Item_nodeset_func ...@@ -427,7 +380,7 @@ class Item_nodeset_func_elementbyindex :public Item_nodeset_func
class Item_xpath_cast_bool :public Item_bool_func class Item_xpath_cast_bool :public Item_bool_func
{ {
String *pxml; String *pxml;
String tmp_value; NativeNodesetBuffer tmp_native_value;
public: public:
Item_xpath_cast_bool(THD *thd, Item *a, String *pxml_arg): Item_xpath_cast_bool(THD *thd, Item *a, String *pxml_arg):
Item_bool_func(thd, a), pxml(pxml_arg) {} Item_bool_func(thd, a), pxml(pxml_arg) {}
...@@ -436,8 +389,8 @@ class Item_xpath_cast_bool :public Item_bool_func ...@@ -436,8 +389,8 @@ class Item_xpath_cast_bool :public Item_bool_func
{ {
if (args[0]->fixed_type_handler() == &type_handler_xpath_nodeset) if (args[0]->fixed_type_handler() == &type_handler_xpath_nodeset)
{ {
String *flt= args[0]->val_raw(&tmp_value); args[0]->val_native(current_thd, &tmp_native_value);
return flt->length() == sizeof(MY_XPATH_FLT) ? 1 : 0; return tmp_native_value.elements() == 1 ? 1 : 0;
} }
return args[0]->val_real() ? 1 : 0; return args[0]->val_real() ? 1 : 0;
} }
...@@ -466,11 +419,13 @@ class Item_xpath_cast_number :public Item_real_func ...@@ -466,11 +419,13 @@ class Item_xpath_cast_number :public Item_real_func
class Item_nodeset_context_cache :public Item_nodeset_func class Item_nodeset_context_cache :public Item_nodeset_func
{ {
public: public:
String *string_cache; Native *native_cache;
Item_nodeset_context_cache(THD *thd, String *str_arg, String *pxml): Item_nodeset_context_cache(THD *thd, Native *native_arg, String *pxml):
Item_nodeset_func(thd, pxml), string_cache(str_arg) { } Item_nodeset_func(thd, pxml), native_cache(native_arg) { }
String *val_raw(String *res) bool val_native(THD *thd, Native *nodeset)
{ return string_cache; } {
return nodeset->copy(*native_cache);
}
bool fix_length_and_dec() { max_length= MAX_BLOB_WIDTH;; return FALSE; } bool fix_length_and_dec() { max_length= MAX_BLOB_WIDTH;; return FALSE; }
Item *get_copy(THD *thd) Item *get_copy(THD *thd)
{ return get_item_copy<Item_nodeset_context_cache>(thd, this); } { return get_item_copy<Item_nodeset_context_cache>(thd, this); }
...@@ -480,7 +435,7 @@ class Item_nodeset_context_cache :public Item_nodeset_func ...@@ -480,7 +435,7 @@ class Item_nodeset_context_cache :public Item_nodeset_func
class Item_func_xpath_position :public Item_long_func class Item_func_xpath_position :public Item_long_func
{ {
String *pxml; String *pxml;
String tmp_value; NativeNodesetBuffer tmp_native_value;
public: public:
Item_func_xpath_position(THD *thd, Item *a, String *p): Item_func_xpath_position(THD *thd, Item *a, String *p):
Item_long_func(thd, a), pxml(p) {} Item_long_func(thd, a), pxml(p) {}
...@@ -488,9 +443,9 @@ class Item_func_xpath_position :public Item_long_func ...@@ -488,9 +443,9 @@ class Item_func_xpath_position :public Item_long_func
bool fix_length_and_dec() { max_length=10; return FALSE; } bool fix_length_and_dec() { max_length=10; return FALSE; }
longlong val_int() longlong val_int()
{ {
String *flt= args[0]->val_raw(&tmp_value); args[0]->val_native(current_thd, &tmp_native_value);
if (flt->length() == sizeof(MY_XPATH_FLT)) if (tmp_native_value.elements() == 1)
return ((MY_XPATH_FLT*)flt->ptr())->pos + 1; return tmp_native_value.element(0).pos + 1;
return 0; return 0;
} }
Item *get_copy(THD *thd) Item *get_copy(THD *thd)
...@@ -501,7 +456,7 @@ class Item_func_xpath_position :public Item_long_func ...@@ -501,7 +456,7 @@ class Item_func_xpath_position :public Item_long_func
class Item_func_xpath_count :public Item_long_func class Item_func_xpath_count :public Item_long_func
{ {
String *pxml; String *pxml;
String tmp_value; NativeNodesetBuffer tmp_native_value;
public: public:
Item_func_xpath_count(THD *thd, Item *a, String *p): Item_func_xpath_count(THD *thd, Item *a, String *p):
Item_long_func(thd, a), pxml(p) {} Item_long_func(thd, a), pxml(p) {}
...@@ -510,11 +465,11 @@ class Item_func_xpath_count :public Item_long_func ...@@ -510,11 +465,11 @@ class Item_func_xpath_count :public Item_long_func
longlong val_int() longlong val_int()
{ {
uint predicate_supplied_context_size; uint predicate_supplied_context_size;
String *res= args[0]->val_raw(&tmp_value); args[0]->val_native(current_thd, &tmp_native_value);
if (res->length() == sizeof(MY_XPATH_FLT) && if (tmp_native_value.elements() == 1 &&
(predicate_supplied_context_size= ((MY_XPATH_FLT*)res->ptr())->size)) (predicate_supplied_context_size= tmp_native_value.element(0).size))
return predicate_supplied_context_size; return predicate_supplied_context_size;
return res->length() / sizeof(MY_XPATH_FLT); return tmp_native_value.elements();
} }
Item *get_copy(THD *thd) Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_xpath_count>(thd, this); } { return get_item_copy<Item_func_xpath_count>(thd, this); }
...@@ -524,7 +479,7 @@ class Item_func_xpath_count :public Item_long_func ...@@ -524,7 +479,7 @@ class Item_func_xpath_count :public Item_long_func
class Item_func_xpath_sum :public Item_real_func class Item_func_xpath_sum :public Item_real_func
{ {
String *pxml; String *pxml;
String tmp_value; NativeNodesetBuffer tmp_native_value;
public: public:
Item_func_xpath_sum(THD *thd, Item *a, String *p): Item_func_xpath_sum(THD *thd, Item *a, String *p):
Item_real_func(thd, a), pxml(p) {} Item_real_func(thd, a), pxml(p) {}
...@@ -533,9 +488,9 @@ class Item_func_xpath_sum :public Item_real_func ...@@ -533,9 +488,9 @@ class Item_func_xpath_sum :public Item_real_func
double val_real() double val_real()
{ {
double sum= 0; double sum= 0;
String *res= args[0]->val_raw(&tmp_value); args[0]->val_native(current_thd, &tmp_native_value);
MY_XPATH_FLT *fltbeg= (MY_XPATH_FLT*) res->ptr(); MY_XPATH_FLT *fltbeg= (MY_XPATH_FLT*) tmp_native_value.ptr();
MY_XPATH_FLT *fltend= (MY_XPATH_FLT*) (res->ptr() + res->length()); MY_XPATH_FLT *fltend= (MY_XPATH_FLT*) tmp_native_value.end();
uint numnodes= pxml->length() / sizeof(MY_XML_NODE); uint numnodes= pxml->length() / sizeof(MY_XML_NODE);
MY_XML_NODE *nodebeg= (MY_XML_NODE*) pxml->ptr(); MY_XML_NODE *nodebeg= (MY_XML_NODE*) pxml->ptr();
...@@ -596,7 +551,7 @@ class Item_string_xml_non_const: public Item_string ...@@ -596,7 +551,7 @@ class Item_string_xml_non_const: public Item_string
class Item_nodeset_to_const_comparator :public Item_bool_func class Item_nodeset_to_const_comparator :public Item_bool_func
{ {
String *pxml; String *pxml;
String tmp_nodeset; NativeNodesetBuffer tmp_nodeset;
public: public:
Item_nodeset_to_const_comparator(THD *thd, Item *nodeset, Item *cmpfunc, Item_nodeset_to_const_comparator(THD *thd, Item *nodeset, Item *cmpfunc,
String *p): String *p):
...@@ -617,9 +572,9 @@ class Item_nodeset_to_const_comparator :public Item_bool_func ...@@ -617,9 +572,9 @@ class Item_nodeset_to_const_comparator :public Item_bool_func
Item_func *comp= (Item_func*)args[1]; Item_func *comp= (Item_func*)args[1];
Item_string_xml_non_const *fake= Item_string_xml_non_const *fake=
(Item_string_xml_non_const*)(comp->arguments()[0]); (Item_string_xml_non_const*)(comp->arguments()[0]);
String *res= args[0]->val_raw(&tmp_nodeset); args[0]->val_native(current_thd, &tmp_nodeset);
MY_XPATH_FLT *fltbeg= (MY_XPATH_FLT*) res->ptr(); MY_XPATH_FLT *fltbeg= (MY_XPATH_FLT*) tmp_nodeset.ptr();
MY_XPATH_FLT *fltend= (MY_XPATH_FLT*) (res->ptr() + res->length()); MY_XPATH_FLT *fltend= (MY_XPATH_FLT*) tmp_nodeset.end();
MY_XML_NODE *nodebeg= (MY_XML_NODE*) pxml->ptr(); MY_XML_NODE *nodebeg= (MY_XML_NODE*) pxml->ptr();
uint numnodes= pxml->length() / sizeof(MY_XML_NODE); uint numnodes= pxml->length() / sizeof(MY_XML_NODE);
...@@ -648,32 +603,32 @@ class Item_nodeset_to_const_comparator :public Item_bool_func ...@@ -648,32 +603,32 @@ class Item_nodeset_to_const_comparator :public Item_bool_func
}; };
String *Item_nodeset_func_rootelement::val_raw(String *nodeset) bool Item_nodeset_func_rootelement::val_native(THD *thd, Native *nodeset)
{ {
nodeset->length(0); nodeset->length(0);
((XPathFilter*)nodeset)->append_element(0, 0); return MY_XPATH_FLT(0, 0).append_to(nodeset);
return 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); uint num_nodes= pxml->length() / sizeof(MY_XML_NODE);
String set0, *s0= args[0]->val_raw(&set0); NativeNodesetBuffer set0, set1;
String set1, *s1= args[1]->val_raw(&set1); args[0]->val_native(thd, &set0);
args[1]->val_native(thd, &set1);
String both_str; String both_str;
both_str.alloc(num_nodes); both_str.alloc(num_nodes);
char *both= (char*) both_str.ptr(); char *both= (char*) both_str.ptr();
bzero((void*)both, num_nodes); bzero((void*)both, num_nodes);
MY_XPATH_FLT *flt; MY_XPATH_FLT *flt;
fltbeg= (MY_XPATH_FLT*) s0->ptr(); fltbeg= (MY_XPATH_FLT*) set0.ptr();
fltend= (MY_XPATH_FLT*) (s0->ptr() + s0->length()); fltend= (MY_XPATH_FLT*) set0.end();
for (flt= fltbeg; flt < fltend; flt++) for (flt= fltbeg; flt < fltend; flt++)
both[flt->num]= 1; both[flt->num]= 1;
fltbeg= (MY_XPATH_FLT*) s1->ptr(); fltbeg= (MY_XPATH_FLT*) set1.ptr();
fltend= (MY_XPATH_FLT*) (s1->ptr() + s1->length()); fltend= (MY_XPATH_FLT*) set1.end();
for (flt= fltbeg; flt < fltend; flt++) for (flt= fltbeg; flt < fltend; flt++)
both[flt->num]= 1; both[flt->num]= 1;
...@@ -681,29 +636,29 @@ String * Item_nodeset_func_union::val_raw(String *nodeset) ...@@ -681,29 +636,29 @@ String * Item_nodeset_func_union::val_raw(String *nodeset)
for (uint i= 0, pos= 0; i < num_nodes; i++) for (uint i= 0, pos= 0; i < num_nodes; i++)
{ {
if (both[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++) for (MY_XPATH_FLT *flt= fltbeg; flt < fltend; flt++)
{ {
uint pos= 0; uint pos= 0;
MY_XML_NODE *self= &nodebeg[flt->num]; MY_XML_NODE *self= &nodebeg[flt->num];
if (validname(self)) 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++) for (MY_XPATH_FLT *flt= fltbeg; flt < fltend; flt++)
{ {
MY_XML_NODE *self= &nodebeg[flt->num]; MY_XML_NODE *self= &nodebeg[flt->num];
...@@ -715,40 +670,40 @@ String *Item_nodeset_func_childbyname::val_raw(String *nodeset) ...@@ -715,40 +670,40 @@ String *Item_nodeset_func_childbyname::val_raw(String *nodeset)
if ((node->parent == flt->num) && if ((node->parent == flt->num) &&
(node->type == MY_XML_NODE_TAG) && (node->type == MY_XML_NODE_TAG) &&
validname(node)) 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++) for (MY_XPATH_FLT *flt= fltbeg; flt < fltend; flt++)
{ {
uint pos= 0; uint pos= 0;
MY_XML_NODE *self= &nodebeg[flt->num]; MY_XML_NODE *self= &nodebeg[flt->num];
if (need_self && validname(self)) 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++) for (uint j= flt->num + 1 ; j < numnodes ; j++)
{ {
MY_XML_NODE *node= &nodebeg[j]; MY_XML_NODE *node= &nodebeg[j];
if (node->level <= self->level) if (node->level <= self->level)
break; break;
if ((node->type == MY_XML_NODE_TAG) && validname(node)) 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; char *active;
String active_str; String active_str;
prepare(nodeset); prepare(thd, nodeset);
active_str.alloc(numnodes); active_str.alloc(numnodes);
active= (char*) active_str.ptr(); active= (char*) active_str.ptr();
bzero((void*)active, numnodes); bzero((void*)active, numnodes);
...@@ -780,17 +735,17 @@ String *Item_nodeset_func_ancestorbyname::val_raw(String *nodeset) ...@@ -780,17 +735,17 @@ String *Item_nodeset_func_ancestorbyname::val_raw(String *nodeset)
for (uint j= 0; j < numnodes ; j++) for (uint j= 0; j < numnodes ; j++)
{ {
if (active[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; char *active;
String active_str; String active_str;
prepare(nodeset); prepare(thd, nodeset);
active_str.alloc(numnodes); active_str.alloc(numnodes);
active= (char*) active_str.ptr(); active= (char*) active_str.ptr();
bzero((void*)active, numnodes); bzero((void*)active, numnodes);
...@@ -803,15 +758,15 @@ String *Item_nodeset_func_parentbyname::val_raw(String *nodeset) ...@@ -803,15 +758,15 @@ String *Item_nodeset_func_parentbyname::val_raw(String *nodeset)
for (uint j= 0, pos= 0; j < numnodes ; j++) for (uint j= 0, pos= 0; j < numnodes ; j++)
{ {
if (active[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++) for (MY_XPATH_FLT *flt= fltbeg; flt < fltend; flt++)
{ {
MY_XML_NODE *self= &nodebeg[flt->num]; MY_XML_NODE *self= &nodebeg[flt->num];
...@@ -823,52 +778,50 @@ String *Item_nodeset_func_attributebyname::val_raw(String *nodeset) ...@@ -823,52 +778,50 @@ String *Item_nodeset_func_attributebyname::val_raw(String *nodeset)
if ((node->parent == flt->num) && if ((node->parent == flt->num) &&
(node->type == MY_XML_NODE_ATTR) && (node->type == MY_XML_NODE_ATTR) &&
validname(node)) 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_nodeset_func *nodeset_func= (Item_nodeset_func*) args[0];
Item_func *comp_func= (Item_func*)args[1]; Item_func *comp_func= (Item_func*)args[1];
uint pos= 0, size; uint pos= 0, size;
prepare(str); prepare(thd, str);
size= (uint)(fltend - fltbeg); size= (uint)(fltend - fltbeg);
for (MY_XPATH_FLT *flt= fltbeg; flt < fltend; flt++) for (MY_XPATH_FLT *flt= fltbeg; flt < fltend; flt++)
{ {
nodeset_func->context_cache.length(0); nodeset_func->context_cache.length(0);
((XPathFilter*)(&nodeset_func->context_cache))->append_element(flt->num, MY_XPATH_FLT(flt->num, flt->pos, size).
flt->pos, append_to(&nodeset_func->context_cache);
size);
if (comp_func->val_int()) 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]; Item_nodeset_func *nodeset_func= (Item_nodeset_func*) args[0];
prepare(nodeset); prepare(thd, nodeset);
MY_XPATH_FLT *flt; MY_XPATH_FLT *flt;
uint pos, size= (uint)(fltend - fltbeg); uint pos, size= (uint)(fltend - fltbeg);
for (pos= 0, flt= fltbeg; flt < fltend; flt++) for (pos= 0, flt= fltbeg; flt < fltend; flt++)
{ {
nodeset_func->context_cache.length(0); nodeset_func->context_cache.length(0);
((XPathFilter*)(&nodeset_func->context_cache))->append_element(flt->num, MY_XPATH_FLT(flt->num, flt->pos, size).
flt->pos, append_to(&nodeset_func->context_cache);
size);
int index= (int) (args[1]->val_int()) - 1; int index= (int) (args[1]->val_int()) - 1;
if (index >= 0 && if (index >= 0 &&
(flt->pos == (uint) index || (flt->pos == (uint) index ||
(args[1]->type_handler()->is_bool_type()))) (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) ...@@ -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)) while (my_xpath_parse_term(xpath, MY_XPATH_LEX_LB))
{ {
Item *prev_context= xpath->context; Item *prev_context= xpath->context;
String *context_cache; Native *context_cache;
context_cache= &((Item_nodeset_func*)xpath->context)->context_cache; context_cache= &((Item_nodeset_func*)xpath->context)->context_cache;
xpath->context= new (xpath->thd->mem_root) xpath->context= new (xpath->thd->mem_root)
Item_nodeset_context_cache(xpath->thd, context_cache, xpath->pxml); Item_nodeset_context_cache(xpath->thd, context_cache, xpath->pxml);
...@@ -3070,19 +3023,20 @@ bool Item_func_xml_update::collect_result(String *str, ...@@ -3070,19 +3023,20 @@ bool Item_func_xml_update::collect_result(String *str,
String *Item_func_xml_update::val_str(String *str) String *Item_func_xml_update::val_str(String *str)
{ {
String *nodeset, *rep; String *rep;
null_value= 0; null_value= 0;
if (!nodeset_func || get_xml(&xml) || if (!nodeset_func || get_xml(&xml) ||
!(rep= args[2]->val_str(&tmp_value3)) || !(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; null_value= 1;
return 0; return 0;
} }
MY_XPATH_FLT *fltbeg= (MY_XPATH_FLT*) nodeset->ptr(); MY_XPATH_FLT *fltbeg= (MY_XPATH_FLT*) tmp_native_value2.ptr();
MY_XPATH_FLT *fltend= (MY_XPATH_FLT*) (nodeset->ptr() + nodeset->length()); MY_XPATH_FLT *fltend= (MY_XPATH_FLT*) tmp_native_value2.end();
/* Allow replacing of one tag only */ /* Allow replacing of one tag only */
if (fltend - fltbeg != 1) if (fltend - fltbeg != 1)
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define ITEM_XMLFUNC_INCLUDED #define ITEM_XMLFUNC_INCLUDED
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. /* 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 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 it under the terms of the GNU General Public License as published by
...@@ -23,6 +24,42 @@ ...@@ -23,6 +24,42 @@
typedef struct my_xml_node_st MY_XML_NODE; 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 class Item_xml_str_func: public Item_str_func
{ {
protected: protected:
...@@ -103,7 +140,8 @@ class Item_func_xml_extractvalue: public Item_xml_str_func ...@@ -103,7 +140,8 @@ class Item_func_xml_extractvalue: public Item_xml_str_func
class Item_func_xml_update: public Item_xml_str_func 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, bool collect_result(String *str,
const MY_XML_NODE *cut, const MY_XML_NODE *cut,
const String *replace); const String *replace);
......
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