Commit 1a3cb50c authored by unknown's avatar unknown
Browse files

Bug#18170: XML: ExtractValue(): XPath expression can't use QNames (colon in names)

Problem source:
Qualified names (aka QName) didn't work as tag names and attribute names,
because the parser lacked a real rule to scan QName, so it understood
only non-qualified names without prefixes.

Solution:
New rule was added to check both "ident" and "ident:ident" sequences.


mysql-test/r/xml.result:
  Adding test case
mysql-test/t/xml.test:
  Adding test case
sql/item_xmlfunc.cc:
  Adding real QName parser rule and using it in NodeTest rule.
parent 3ef01486
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -641,3 +641,12 @@ CALL p2();
EXTRACTVALUE(p,'/Ñ/r')
A
DROP PROCEDURE p2;
select extractValue('<ns:element xmlns:ns="myns"/>','count(ns:element)');
extractValue('<ns:element xmlns:ns="myns"/>','count(ns:element)')
1
select extractValue('<ns:element xmlns:ns="myns">a</ns:element>','/ns:element');
extractValue('<ns:element xmlns:ns="myns">a</ns:element>','/ns:element')
a
select extractValue('<ns:element xmlns:ns="myns">a</ns:element>','/ns:element/@xmlns:ns');
extractValue('<ns:element xmlns:ns="myns">a</ns:element>','/ns:element/@xmlns:ns')
myns
+8 −0
Original line number Diff line number Diff line
@@ -321,3 +321,11 @@ END//
DELIMITER ;//
CALL p2();
DROP PROCEDURE p2;

#
# Bug#18170: XML: ExtractValue():
# XPath expression can't use QNames (colon in names)
#
select extractValue('<ns:element xmlns:ns="myns"/>','count(ns:element)');
select extractValue('<ns:element xmlns:ns="myns">a</ns:element>','/ns:element');
select extractValue('<ns:element xmlns:ns="myns">a</ns:element>','/ns:element/@xmlns:ns');
+25 −1
Original line number Diff line number Diff line
@@ -2266,6 +2266,30 @@ static int my_xpath_parse_Number(MY_XPATH *xpath)
}


/*
  QName grammar can be found in a separate document
  http://www.w3.org/TR/REC-xml-names/#NT-QName

  [6] 	QName     ::= (Prefix ':')? LocalPart
  [7] 	Prefix    ::= NCName
  [8] 	LocalPart ::= NCName
*/
static int
my_xpath_parse_QName(MY_XPATH *xpath)
{
  const char *beg;
  if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT))
    return 0;
  beg= xpath->prevtok.beg;
  if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_COLON))
    return 1; /* Non qualified name */
  if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT))
    return 0;
  xpath->prevtok.beg= beg;
  return 1;
}


/*
  Scan Variable reference

@@ -2299,7 +2323,7 @@ my_xpath_parse_VariableReference(MY_XPATH *xpath)
static int
my_xpath_parse_NodeTest_QName(MY_XPATH *xpath)
{
  if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT))
  if (!my_xpath_parse_QName(xpath))
    return 0;
  DBUG_ASSERT(xpath->context);
  uint len= xpath->prevtok.end - xpath->prevtok.beg;