diff options
author | bar@mysql.com <> | 2006-12-27 18:14:28 +0400 |
---|---|---|
committer | bar@mysql.com <> | 2006-12-27 18:14:28 +0400 |
commit | 01be66ad54c3d01a83161a17c90ca59f8fc50629 (patch) | |
tree | f484b0fb186a6aebe386231631f2225f603d578d /sql/item_xmlfunc.cc | |
parent | f495b5f92300f662fffc51cb1a55e3d2d8baf387 (diff) | |
download | mariadb-git-01be66ad54c3d01a83161a17c90ca59f8fc50629.tar.gz |
Bug#24747 XPath error with the node name "Text"
Diffstat (limited to 'sql/item_xmlfunc.cc')
-rw-r--r-- | sql/item_xmlfunc.cc | 92 |
1 files changed, 76 insertions, 16 deletions
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 966bae43984..d0b80ba49c0 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -1047,12 +1047,12 @@ static struct my_xpath_keyword_names_st my_keyword_names[] = {MY_XPATH_LEX_OR , "or" , 2, 0 }, {MY_XPATH_LEX_DIV , "div" , 3, 0 }, {MY_XPATH_LEX_MOD , "mod" , 3, 0 }, - - {MY_XPATH_LEX_NODETYPE, "comment" , 7, 0 }, - {MY_XPATH_LEX_NODETYPE, "text" , 4, 0 }, - {MY_XPATH_LEX_NODETYPE, "processing-instruction" , 22,0 }, - {MY_XPATH_LEX_NODETYPE, "node" , 4, 0 }, - + {0,NULL,0,0} +}; + + +static struct my_xpath_keyword_names_st my_axis_names[]= +{ {MY_XPATH_LEX_AXIS,"ancestor" , 8,MY_XPATH_AXIS_ANCESTOR }, {MY_XPATH_LEX_AXIS,"ancestor-or-self" ,16,MY_XPATH_AXIS_ANCESTOR_OR_SELF }, {MY_XPATH_LEX_AXIS,"attribute" , 9,MY_XPATH_AXIS_ATTRIBUTE }, @@ -1066,7 +1066,16 @@ static struct my_xpath_keyword_names_st my_keyword_names[] = {MY_XPATH_LEX_AXIS,"preceding" , 9,MY_XPATH_AXIS_PRECEDING }, {MY_XPATH_LEX_AXIS,"preceding-sibling" ,17,MY_XPATH_AXIS_PRECEDING_SIBLING }, {MY_XPATH_LEX_AXIS,"self" , 4,MY_XPATH_AXIS_SELF }, + {0,NULL,0,0} +}; + +static struct my_xpath_keyword_names_st my_nodetype_names[]= +{ + {MY_XPATH_LEX_NODETYPE, "comment" , 7, 0 }, + {MY_XPATH_LEX_NODETYPE, "text" , 4, 0 }, + {MY_XPATH_LEX_NODETYPE, "processing-instruction" , 22,0 }, + {MY_XPATH_LEX_NODETYPE, "node" , 4, 0 }, {0,NULL,0,0} }; @@ -1081,11 +1090,14 @@ static struct my_xpath_keyword_names_st my_keyword_names[] = - Token type, on lookup success. - MY_XPATH_LEX_IDENT, on lookup failure. */ -static int my_xpath_keyword(MY_XPATH *x, const char *beg, const char *end) +static int +my_xpath_keyword(MY_XPATH *x, + struct my_xpath_keyword_names_st *keyword_names, + const char *beg, const char *end) { struct my_xpath_keyword_names_st *k; size_t length= end-beg; - for (k= my_keyword_names; k->name; k++) + for (k= keyword_names; k->name; k++) { if (length == k->length && !strncasecmp(beg, k->name, length)) { @@ -1371,15 +1383,32 @@ my_xpath_lex_scan(MY_XPATH *xpath, beg+= length) /* no op */; lex->end= beg; - // check if a function call - if (*beg == '(' && (xpath->func= my_xpath_function(lex->beg, beg))) + if (beg < end) { - lex->term= MY_XPATH_LEX_FUNC; - return; + if (*beg == '(') + { + /* + check if a function call, e.g.: count(/a/b) + or a nodetype test, e.g.: /a/b/text() + */ + if ((xpath->func= my_xpath_function(lex->beg, beg))) + lex->term= MY_XPATH_LEX_FUNC; + else + lex->term= my_xpath_keyword(xpath, my_nodetype_names, + lex->beg, beg); + return; + } + // check if an axis specifier, e.g.: /a/b/child::* + else if (*beg == ':' && beg + 1 < end && beg[1] == ':') + { + lex->term= my_xpath_keyword(xpath, my_axis_names, + lex->beg, beg); + return; + } } - // check if a keyword - lex->term= my_xpath_keyword(xpath, lex->beg, beg); + lex->term= my_xpath_keyword(xpath, my_keyword_names, + lex->beg, beg); return; } @@ -2334,6 +2363,36 @@ static int my_xpath_parse_Number(MY_XPATH *xpath) /* + Scan NCName. + + SYNOPSYS + + The keywords AND, OR, MOD, DIV are valid identitiers + when they are in identifier context: + + SELECT + ExtractValue('<and><or><mod><div>VALUE</div></mod></or></and>', + '/and/or/mod/div') + -> VALUE + + RETURN + 1 - success + 0 - failure +*/ + +static int +my_xpath_parse_NCName(MY_XPATH *xpath) +{ + return + my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT) || + my_xpath_parse_term(xpath, MY_XPATH_LEX_AND) || + my_xpath_parse_term(xpath, MY_XPATH_LEX_OR) || + my_xpath_parse_term(xpath, MY_XPATH_LEX_MOD) || + my_xpath_parse_term(xpath, MY_XPATH_LEX_DIV) ? 1 : 0; +} + + +/* QName grammar can be found in a separate document http://www.w3.org/TR/REC-xml-names/#NT-QName @@ -2341,16 +2400,17 @@ static int my_xpath_parse_Number(MY_XPATH *xpath) [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)) + if (!my_xpath_parse_NCName(xpath)) 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)) + if (!my_xpath_parse_NCName(xpath)) return 0; xpath->prevtok.beg= beg; return 1; |