summaryrefslogtreecommitdiff
path: root/sql/item_xmlfunc.cc
diff options
context:
space:
mode:
authorbar@mysql.com/bar.myoffice.izhnet.ru <>2007-05-08 13:32:29 +0500
committerbar@mysql.com/bar.myoffice.izhnet.ru <>2007-05-08 13:32:29 +0500
commit8bc4ded6aa7d4cda4d6f7f81e6d67ad733f6e800 (patch)
treebf966c606772dae56fc754b02433451de35e99c6 /sql/item_xmlfunc.cc
parent68cc7dde31b6cf1a72fea3e3e6d3aa62bd3bacf9 (diff)
downloadmariadb-git-8bc4ded6aa7d4cda4d6f7f81e6d67ad733f6e800.tar.gz
Bug#26518 XPath and variables problem
Problem: XPath variables didn't work. Fix: adding variables support, both user-defined and sp local variables are now supported by XPath.
Diffstat (limited to 'sql/item_xmlfunc.cc')
-rw-r--r--sql/item_xmlfunc.cc75
1 files changed, 66 insertions, 9 deletions
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index 26474990644..52962b3558e 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -19,7 +19,7 @@
#include "mysql_priv.h"
#include "my_xml.h"
-
+#include "sp_pcontext.h"
/*
TODO: future development directions:
@@ -2412,21 +2412,78 @@ my_xpath_parse_QName(MY_XPATH *xpath)
}
-/*
+/**
Scan Variable reference
- SYNOPSYS
+ @details Implements parsing of two syntax structures:
- [36] VariableReference ::= '$' QName
- RETURN
- 1 - success
- 0 - failure
+ 1. Standard XPath syntax [36], for SP variables:
+
+ VariableReference ::= '$' QName
+
+ Finds a SP variable with the given name.
+ If outside of a SP context, or variable with
+ the given name doesn't exists, then error is returned.
+
+ 2. Non-standard syntax - MySQL extension for user variables:
+
+ VariableReference ::= '$' '@' QName
+
+ Item, corresponding to the variable, is returned
+ in xpath->item in both cases.
+
+ @param xpath pointer to XPath structure
+
+ @return Operation status
+ @retval 1 Success
+ @retval 0 Failure
*/
+
static int
my_xpath_parse_VariableReference(MY_XPATH *xpath)
{
- return my_xpath_parse_term(xpath, MY_XPATH_LEX_DOLLAR) &&
- my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT);
+ LEX_STRING name;
+ int user_var;
+ const char *dollar_pos;
+ if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_DOLLAR) ||
+ (!(dollar_pos= xpath->prevtok.beg)) ||
+ (!((user_var= my_xpath_parse_term(xpath, MY_XPATH_LEX_AT) &&
+ my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT))) &&
+ !my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT)))
+ return 0;
+
+ name.length= xpath->prevtok.end - xpath->prevtok.beg;
+ name.str= (char*) xpath->prevtok.beg;
+
+ if (user_var)
+ xpath->item= new Item_func_get_user_var(name);
+ else
+ {
+ sp_variable_t *spv;
+ sp_pcontext *spc;
+ LEX *lex;
+ if ((lex= current_thd->lex) &&
+ (spc= lex->spcont) &&
+ (spv= spc->find_variable(&name)))
+ {
+ Item_splocal *splocal= new Item_splocal(name, spv->offset, spv->type, 0);
+#ifndef DBUG_OFF
+ if (splocal)
+ splocal->m_sp= lex->sphead;
+#endif
+ xpath->item= (Item*) splocal;
+ }
+ else
+ {
+ xpath->item= NULL;
+ DBUG_ASSERT(xpath->query.end > dollar_pos);
+ uint len= xpath->query.end - dollar_pos;
+ set_if_smaller(len, 32);
+ my_printf_error(ER_UNKNOWN_ERROR, "Unknown XPATH variable at: '%.*s'",
+ MYF(0), len, dollar_pos);
+ }
+ }
+ return xpath->item ? 1 : 0;
}