Commit e4bdc16f authored by msvensson@neptunus.(none)'s avatar msvensson@neptunus.(none)

Merge bk-internal:/home/bk/mysql-5.1-new

into  neptunus.(none):/home/msvensson/mysql/bug17137/my51-bug17137
parents 80c8ba2f 8c2fb88a
...@@ -561,6 +561,42 @@ A B C ...@@ -561,6 +561,42 @@ A B C
select extractvalue('<A_B>A</A_B>','/A_B'); select extractvalue('<A_B>A</A_B>','/A_B');
extractvalue('<A_B>A</A_B>','/A_B') extractvalue('<A_B>A</A_B>','/A_B')
A 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")]'); select extractvalue('<a>Jack</a>','/a[contains(../a,"J")]');
extractvalue('<a>Jack</a>','/a[contains(../a,"J")]') extractvalue('<a>Jack</a>','/a[contains(../a,"J")]')
Jack Jack
......
...@@ -255,6 +255,21 @@ select extractvalue('<a>A<b>B<c>C</c></b></a>','/a/descendant-or-self::*'); ...@@ -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'); 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() # Bug#16316: XML: extractvalue() is case-sensitive with contains()
# #
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
2. add nodeset_to_nodeset_comparator 2. add nodeset_to_nodeset_comparator
3. add lacking functions: 3. add lacking functions:
- name() - name()
- last()
- lang() - lang()
- string() - string()
- id() - id()
...@@ -75,6 +74,7 @@ typedef struct my_xpath_flt_st ...@@ -75,6 +74,7 @@ typedef struct my_xpath_flt_st
{ {
uint num; /* absolute position in MY_XML_NODE array */ uint num; /* absolute position in MY_XML_NODE array */
uint pos; /* relative position in context */ uint pos; /* relative position in context */
uint size; /* context size */
} MY_XPATH_FLT; } MY_XPATH_FLT;
...@@ -123,6 +123,15 @@ class XPathFilter :public String ...@@ -123,6 +123,15 @@ class XPathFilter :public String
MY_XPATH_FLT add; MY_XPATH_FLT add;
add.num= num; add.num= num;
add.pos= pos; 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); return append_element(&add);
} }
inline MY_XPATH_FLT *element(uint i) inline MY_XPATH_FLT *element(uint i)
...@@ -455,7 +464,11 @@ class Item_func_xpath_count :public Item_int_func ...@@ -455,7 +464,11 @@ class Item_func_xpath_count :public Item_int_func
void fix_length_and_dec() { max_length=10; } void fix_length_and_dec() { max_length=10; }
longlong val_int() longlong val_int()
{ {
uint predicate_supplied_context_size;
String *res= args[0]->val_nodeset(&tmp_value); 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); return res->length() / sizeof(MY_XPATH_FLT);
} }
}; };
...@@ -735,13 +748,15 @@ String *Item_nodeset_func_predicate::val_nodeset(String *str) ...@@ -735,13 +748,15 @@ String *Item_nodeset_func_predicate::val_nodeset(String *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; uint pos= 0, size;
prepare(str); prepare(str);
size= 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, ((XPathFilter*)(&nodeset_func->context_cache))->append_element(flt->num,
flt->pos); flt->pos,
size);
if (comp_func->val_int()) if (comp_func->val_int())
((XPathFilter*)str)->append_element(flt->num, pos++); ((XPathFilter*)str)->append_element(flt->num, pos++);
} }
...@@ -751,17 +766,19 @@ String *Item_nodeset_func_predicate::val_nodeset(String *str) ...@@ -751,17 +766,19 @@ String *Item_nodeset_func_predicate::val_nodeset(String *str)
String *Item_nodeset_func_elementbyindex::val_nodeset(String *nodeset) String *Item_nodeset_func_elementbyindex::val_nodeset(String *nodeset)
{ {
Item_nodeset_func *nodeset_func= (Item_nodeset_func*) args[0];
prepare(nodeset); prepare(nodeset);
int index= args[1]->val_int() - 1; MY_XPATH_FLT *flt;
if (index >= 0) uint pos, size= fltend - fltbeg;
for (pos= 0, flt= fltbeg; flt < fltend; flt++)
{ {
MY_XPATH_FLT *flt; nodeset_func->context_cache.length(0);
uint pos; ((XPathFilter*)(&nodeset_func->context_cache))->append_element(flt->num,
for (pos= 0, flt= fltbeg; flt < fltend; flt++) flt->pos,
{ size);
if (flt->pos == (uint) index || args[1]->is_bool_func()) int index= args[1]->val_int() - 1;
((XPathFilter*)nodeset)->append_element(flt->num, pos++); if (index >= 0 && (flt->pos == (uint) index || args[1]->is_bool_func()))
} ((XPathFilter*)nodeset)->append_element(flt->num, pos++);
} }
return nodeset; return nodeset;
} }
......
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