diff options
author | Georgi Kodinov <Georgi.Kodinov@Oracle.com> | 2011-05-03 10:48:24 +0300 |
---|---|---|
committer | Georgi Kodinov <Georgi.Kodinov@Oracle.com> | 2011-05-03 10:48:24 +0300 |
commit | d33bed3c23259bd4a45d909ffa26b88176a02978 (patch) | |
tree | daf416307940106fbee129775b57aa569d64557a /sql/item_xmlfunc.cc | |
parent | 1019b95877bd1a8f581e58a9f2d52ec52d23e5b7 (diff) | |
download | mariadb-git-d33bed3c23259bd4a45d909ffa26b88176a02978.tar.gz |
Bug #12375190: UPDATEXML CRASHES ON SIMPLE INPUTS
The XPATH implementation was not handling correctly the XPATH
production #19
(http://www.w3.org/TR/1999/REC-xpath-19991116/#node-sets),
namely
PathExpr ::= | FilterExpr '/' RelativeLocationPath
| FilterExpr '//' RelativeLocationPath
It was lacking context for the RelativeLocationPath and it was just
ignoring the second slash instead of treating it as a different axis
specifier.
Fixed the above two problems and added a test case.
Diffstat (limited to 'sql/item_xmlfunc.cc')
-rw-r--r-- | sql/item_xmlfunc.cc | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 49d18b1bb0f..531b9e11cb5 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -1973,6 +1973,9 @@ static int my_xpath_parse_UnionExpr(MY_XPATH *xpath) static int my_xpath_parse_FilterExpr_opt_slashes_RelativeLocationPath(MY_XPATH *xpath) { + Item *context= xpath->context; + int rc; + if (!my_xpath_parse_FilterExpr(xpath)) return 0; @@ -1986,8 +1989,22 @@ my_xpath_parse_FilterExpr_opt_slashes_RelativeLocationPath(MY_XPATH *xpath) return 0; } - my_xpath_parse_term(xpath, MY_XPATH_LEX_SLASH); - return my_xpath_parse_RelativeLocationPath(xpath); + /* + The context for the next relative path is the nodeset + returned by FilterExpr + */ + xpath->context= xpath->item; + + /* treat double slash (//) as /descendant-or-self::node()/ */ + if (my_xpath_parse_term(xpath, MY_XPATH_LEX_SLASH)) + xpath->context= new Item_nodeset_func_descendantbyname(xpath->context, + "*", 1, xpath->pxml, 1); + rc= my_xpath_parse_RelativeLocationPath(xpath); + + /* push back the context and restore the item */ + xpath->item= xpath->context; + xpath->context= context; + return rc; } static int my_xpath_parse_PathExpr(MY_XPATH *xpath) { |