Loading mysql-test/r/xml.result +36 −0 Original line number Diff line number Diff line Loading @@ -561,6 +561,42 @@ A B C select extractvalue('<A_B>A</A_B>','/A_B'); extractvalue('<A_B>A</A_B>','/A_B') A select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[position()]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[position()]') B1 B2 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=last()]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=last()]') B1 B2 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()]') B2 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()-1]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()-1]') B1 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=1]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=1]') select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=2]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=2]') B1 B2 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=position()]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=position()]') B2 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)]') B2 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)-1]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)-1]') B1 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=1]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=1]') select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=2]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=2]') B1 B2 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=position()]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=position()]') B2 select extractvalue('<a>Jack</a>','/a[contains(../a,"J")]'); extractvalue('<a>Jack</a>','/a[contains(../a,"J")]') Jack Loading mysql-test/t/xml.test +15 −0 Original line number Diff line number Diff line Loading @@ -255,6 +255,21 @@ select extractvalue('<a>A<b>B<c>C</c></b></a>','/a/descendant-or-self::*'); # select extractvalue('<A_B>A</A_B>','/A_B'); # # Bug#16318: XML: extractvalue() incorrectly returns last() = 1 # select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[position()]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=last()]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()-1]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=1]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=2]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=position()]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)-1]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=1]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=2]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=position()]'); # # Bug#16316: XML: extractvalue() is case-sensitive with contains() # Loading sql/item_xmlfunc.cc +29 −12 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ 2. add nodeset_to_nodeset_comparator 3. add lacking functions: - name() - last() - lang() - string() - id() Loading Loading @@ -75,6 +74,7 @@ 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; Loading Loading @@ -123,6 +123,15 @@ class XPathFilter :public String 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) Loading Loading @@ -455,7 +464,11 @@ class Item_func_xpath_count :public Item_int_func void fix_length_and_dec() { max_length=10; } longlong val_int() { uint predicate_supplied_context_size; String *res= args[0]->val_nodeset(&tmp_value); if (res->length() == sizeof(MY_XPATH_FLT) && (predicate_supplied_context_size= ((MY_XPATH_FLT*)res->ptr())->size)) return predicate_supplied_context_size; return res->length() / sizeof(MY_XPATH_FLT); } }; Loading Loading @@ -735,13 +748,15 @@ String *Item_nodeset_func_predicate::val_nodeset(String *str) { Item_nodeset_func *nodeset_func= (Item_nodeset_func*) args[0]; Item_func *comp_func= (Item_func*)args[1]; uint pos= 0; uint pos= 0, size; prepare(str); size= 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); flt->pos, size); if (comp_func->val_int()) ((XPathFilter*)str)->append_element(flt->num, pos++); } Loading @@ -751,18 +766,20 @@ String *Item_nodeset_func_predicate::val_nodeset(String *str) String *Item_nodeset_func_elementbyindex::val_nodeset(String *nodeset) { Item_nodeset_func *nodeset_func= (Item_nodeset_func*) args[0]; prepare(nodeset); int index= args[1]->val_int() - 1; if (index >= 0) { MY_XPATH_FLT *flt; uint pos; uint pos, size= fltend - fltbeg; for (pos= 0, flt= fltbeg; flt < fltend; flt++) { if (flt->pos == (uint) index || args[1]->is_bool_func()) nodeset_func->context_cache.length(0); ((XPathFilter*)(&nodeset_func->context_cache))->append_element(flt->num, flt->pos, size); int index= args[1]->val_int() - 1; if (index >= 0 && (flt->pos == (uint) index || args[1]->is_bool_func())) ((XPathFilter*)nodeset)->append_element(flt->num, pos++); } } return nodeset; } Loading Loading
mysql-test/r/xml.result +36 −0 Original line number Diff line number Diff line Loading @@ -561,6 +561,42 @@ A B C select extractvalue('<A_B>A</A_B>','/A_B'); extractvalue('<A_B>A</A_B>','/A_B') A select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[position()]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[position()]') B1 B2 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=last()]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=last()]') B1 B2 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()]') B2 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()-1]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()-1]') B1 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=1]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=1]') select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=2]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=2]') B1 B2 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=position()]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=position()]') B2 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)]') B2 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)-1]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)-1]') B1 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=1]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=1]') select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=2]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=2]') B1 B2 select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=position()]'); extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=position()]') B2 select extractvalue('<a>Jack</a>','/a[contains(../a,"J")]'); extractvalue('<a>Jack</a>','/a[contains(../a,"J")]') Jack Loading
mysql-test/t/xml.test +15 −0 Original line number Diff line number Diff line Loading @@ -255,6 +255,21 @@ select extractvalue('<a>A<b>B<c>C</c></b></a>','/a/descendant-or-self::*'); # select extractvalue('<A_B>A</A_B>','/A_B'); # # Bug#16318: XML: extractvalue() incorrectly returns last() = 1 # select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[position()]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=last()]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()-1]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=1]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=2]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[last()=position()]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)-1]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=1]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=2]'); select extractvalue('<a>A<b>B1</b><b>B2</b></a>','/a/b[count(.)=position()]'); # # Bug#16316: XML: extractvalue() is case-sensitive with contains() # Loading
sql/item_xmlfunc.cc +29 −12 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ 2. add nodeset_to_nodeset_comparator 3. add lacking functions: - name() - last() - lang() - string() - id() Loading Loading @@ -75,6 +74,7 @@ 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; Loading Loading @@ -123,6 +123,15 @@ class XPathFilter :public String 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) Loading Loading @@ -455,7 +464,11 @@ class Item_func_xpath_count :public Item_int_func void fix_length_and_dec() { max_length=10; } longlong val_int() { uint predicate_supplied_context_size; String *res= args[0]->val_nodeset(&tmp_value); if (res->length() == sizeof(MY_XPATH_FLT) && (predicate_supplied_context_size= ((MY_XPATH_FLT*)res->ptr())->size)) return predicate_supplied_context_size; return res->length() / sizeof(MY_XPATH_FLT); } }; Loading Loading @@ -735,13 +748,15 @@ String *Item_nodeset_func_predicate::val_nodeset(String *str) { Item_nodeset_func *nodeset_func= (Item_nodeset_func*) args[0]; Item_func *comp_func= (Item_func*)args[1]; uint pos= 0; uint pos= 0, size; prepare(str); size= 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); flt->pos, size); if (comp_func->val_int()) ((XPathFilter*)str)->append_element(flt->num, pos++); } Loading @@ -751,18 +766,20 @@ String *Item_nodeset_func_predicate::val_nodeset(String *str) String *Item_nodeset_func_elementbyindex::val_nodeset(String *nodeset) { Item_nodeset_func *nodeset_func= (Item_nodeset_func*) args[0]; prepare(nodeset); int index= args[1]->val_int() - 1; if (index >= 0) { MY_XPATH_FLT *flt; uint pos; uint pos, size= fltend - fltbeg; for (pos= 0, flt= fltbeg; flt < fltend; flt++) { if (flt->pos == (uint) index || args[1]->is_bool_func()) nodeset_func->context_cache.length(0); ((XPathFilter*)(&nodeset_func->context_cache))->append_element(flt->num, flt->pos, size); int index= args[1]->val_int() - 1; if (index >= 0 && (flt->pos == (uint) index || args[1]->is_bool_func())) ((XPathFilter*)nodeset)->append_element(flt->num, pos++); } } return nodeset; } Loading