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
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
......
......@@ -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()
#
......
......@@ -30,7 +30,6 @@
2. add nodeset_to_nodeset_comparator
3. add lacking functions:
- name()
- last()
- lang()
- string()
- id()
......@@ -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;
......@@ -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)
......@@ -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);
}
};
......@@ -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++);
}
......@@ -751,17 +766,19 @@ 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, size= fltend - fltbeg;
for (pos= 0, flt= fltbeg; flt < fltend; flt++)
{
MY_XPATH_FLT *flt;
uint pos;
for (pos= 0, flt= fltbeg; flt < fltend; flt++)
{
if (flt->pos == (uint) index || args[1]->is_bool_func())
((XPathFilter*)nodeset)->append_element(flt->num, pos++);
}
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;
}
......
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