From faee72a936226d7ebb2740375418f2966b86e38a Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Mon, 17 Apr 2006 11:49:20 +0500
Subject: [PATCH] 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 | 9 +++++++++
mysql-test/t/xml.test | 8 ++++++++
sql/item_xmlfunc.cc | 26 +++++++++++++++++++++++++-
3 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result
index 7e44673dd78..fdc06a0a2e6 100644
--- a/mysql-test/r/xml.result
+++ b/mysql-test/r/xml.result
@@ -641,3 +641,12 @@ CALL p2();
EXTRACTVALUE(p,'/Ñ/r')
A
DROP PROCEDURE p2;
+select extractValue('','count(ns:element)');
+extractValue('','count(ns:element)')
+1
+select extractValue('a','/ns:element');
+extractValue('a','/ns:element')
+a
+select extractValue('a','/ns:element/@xmlns:ns');
+extractValue('a','/ns:element/@xmlns:ns')
+myns
diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test
index 8ed623883b6..d3e2da46413 100644
--- a/mysql-test/t/xml.test
+++ b/mysql-test/t/xml.test
@@ -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('','count(ns:element)');
+select extractValue('a','/ns:element');
+select extractValue('a','/ns:element/@xmlns:ns');
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index 71900c26c2d..2e70b896af7 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -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;