diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result index 3ed3df546d1..f9b8e9c9dab 100644 --- a/mysql-test/r/xml.result +++ b/mysql-test/r/xml.result @@ -65,6 +65,9 @@ c1 SELECT extractValue(@xml,'/a/child::*'); extractValue(@xml,'/a/child::*') b1 b2 +SELECT extractValue(@xml,'/a/self::*'); +extractValue(@xml,'/a/self::*') +a1 a2 SELECT extractValue(@xml,'/a/descendant::*'); extractValue(@xml,'/a/descendant::*') b1 c1 b2 @@ -546,3 +549,12 @@ select extractvalue('A','/'); ERROR HY000: XPATH syntax error: '>' select extractvalue('bb!','//b!'); ERROR HY000: XPATH syntax error: '!' +select extractvalue('ABC','/a/descendant::*'); +extractvalue('ABC','/a/descendant::*') +B C +select extractvalue('ABC','/a/self::*'); +extractvalue('ABC','/a/self::*') +A +select extractvalue('ABC','/a/descendant-or-self::*'); +extractvalue('ABC','/a/descendant-or-self::*') +A B C diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test index e69ab5ee58b..ee4f7a94ba2 100644 --- a/mysql-test/t/xml.test +++ b/mysql-test/t/xml.test @@ -23,6 +23,7 @@ SELECT extractValue(@xml,'/*/*'); SELECT extractValue(@xml,'/*/*/*'); SELECT extractValue(@xml,'/a/child::*'); +SELECT extractValue(@xml,'/a/self::*'); SELECT extractValue(@xml,'/a/descendant::*'); SELECT extractValue(@xml,'/a/descendant-or-self::*'); SELECT extractValue(@xml,'/a/attribute::*'); @@ -243,3 +244,10 @@ select extractvalue('A','/'); # --error 1105 select extractvalue('bb!','//b!'); + +# +# Bug #16315 XML: extractvalue() handles self badly +# +select extractvalue('ABC','/a/descendant::*'); +select extractvalue('ABC','/a/self::*'); +select extractvalue('ABC','/a/descendant-or-self::*'); diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index aad9e12f6c5..8fc3a2b170c 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -252,6 +252,18 @@ public: }; +/* Returns self */ +class Item_nodeset_func_selfbyname: public Item_nodeset_func_axisbyname +{ +public: + Item_nodeset_func_selfbyname(Item *a, const char *n_arg, uint l_arg, + String *pxml): + Item_nodeset_func_axisbyname(a, n_arg, l_arg, pxml) {} + const char *func_name() const { return "xpath_selfbyname"; } + String *val_nodeset(String *nodeset); +}; + + /* Returns children */ class Item_nodeset_func_childbyname: public Item_nodeset_func_axisbyname { @@ -572,6 +584,20 @@ String * Item_nodeset_func_union::val_nodeset(String *nodeset) } +String *Item_nodeset_func_selfbyname::val_nodeset(String *nodeset) +{ + prepare(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++); + } + return nodeset; +} + + String *Item_nodeset_func_childbyname::val_nodeset(String *nodeset) { prepare(nodeset); @@ -945,6 +971,9 @@ static Item* nametestfunc(MY_XPATH *xpath, case MY_XPATH_AXIS_ATTRIBUTE: res= new Item_nodeset_func_attributebyname(arg, beg, len, xpath->pxml); break; + case MY_XPATH_AXIS_SELF: + res= new Item_nodeset_func_selfbyname(arg, beg, len, xpath->pxml); + break; default: res= new Item_nodeset_func_childbyname(arg, beg, len, xpath->pxml); }