summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2018-01-30 11:07:35 +0400
committerAlexander Barkov <bar@mariadb.org>2018-01-30 11:07:35 +0400
commitdae4fb0acb373e653f826f0ec7bdaf2485ef0b93 (patch)
treeea66ce3c195373f913f45d76286f1c5e4123cfdb
parentb76881a23cff7aeef1126560410613d9d7bbbb7d (diff)
downloadmariadb-git-dae4fb0acb373e653f826f0ec7bdaf2485ef0b93.tar.gz
MDEV-15118 ExtractValue(xml,something_complex) does not work
Item_xml_str_func::fix_fields() used a local "String tmp" as a buffer for args[1]->val_str(). "tmp" was freed at the end of fix_fields(), while Items created during my_xpath_parse() still pointed to its fragments. Adding a new member Item_xml_str_func::m_xpath_query and store the result of args[1]->val_str() into it.
-rw-r--r--mysql-test/r/xml.result12
-rw-r--r--mysql-test/t/xml.test9
-rw-r--r--sql/item_xmlfunc.cc10
-rw-r--r--sql/item_xmlfunc.h1
4 files changed, 30 insertions, 2 deletions
diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result
index 24b95f0e204..b12243bdfb9 100644
--- a/mysql-test/r/xml.result
+++ b/mysql-test/r/xml.result
@@ -1268,5 +1268,17 @@ c1 c2
2 b2
DROP TABLE t1;
#
+# MDEV-15118 ExtractValue(xml,something_complex) does not work
+#
+CREATE TABLE t1 (a TEXT);
+INSERT INTO t1 VALUES (CONCAT('<a>aaa</a>'));
+SELECT ExtractValue(a, '/a') AS a FROM t1;
+a
+aaa
+SELECT ExtractValue(a, FROM_BASE64(TO_BASE64('/a'))) AS a FROM t1;
+a
+aaa
+DROP TABLE t1;
+#
# End of 10.0 tests
#
diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test
index 371fcb72b0d..e9e7864c418 100644
--- a/mysql-test/t/xml.test
+++ b/mysql-test/t/xml.test
@@ -748,6 +748,15 @@ SELECT *,IF(@i:=c1,ExtractValue('<a><b>b1</b><b>b2</b></a>','//b[$@i]'),0) AS xp
SELECT * FROM t1 WHERE c2=IF(@i:=c1,ExtractValue('<a><b>b1</b><b>b2</b></a>','//b[$@i]'),0);
DROP TABLE t1;
+--echo #
+--echo # MDEV-15118 ExtractValue(xml,something_complex) does not work
+--echo #
+
+CREATE TABLE t1 (a TEXT);
+INSERT INTO t1 VALUES (CONCAT('<a>aaa</a>'));
+SELECT ExtractValue(a, '/a') AS a FROM t1;
+SELECT ExtractValue(a, FROM_BASE64(TO_BASE64('/a'))) AS a FROM t1;
+DROP TABLE t1;
--echo #
--echo # End of 10.0 tests
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index c7fd923b0ae..c12f5fd3e87 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -2634,7 +2634,7 @@ void Item_xml_str_func::fix_length_and_dec()
bool Item_xml_str_func::fix_fields(THD *thd, Item **ref)
{
- String *xp, tmp;
+ String *xp;
MY_XPATH xpath;
int rc;
@@ -2662,7 +2662,13 @@ bool Item_xml_str_func::fix_fields(THD *thd, Item **ref)
return true;
}
- if (!(xp= args[1]->val_str(&tmp)))
+ /*
+ Get the XPath query text from args[1] and cache it in m_xpath_query.
+ Its fragments will be referenced by items created during my_xpath_parse(),
+ e.g. by Item_nodeset_func_axisbyname::node_name.
+ */
+ if (!(xp= args[1]->val_str(&m_xpath_query)) ||
+ (xp != &m_xpath_query && m_xpath_query.copy(*xp)))
return false; // Will return NULL
my_xpath_init(&xpath);
xpath.cs= collation.collation;
diff --git a/sql/item_xmlfunc.h b/sql/item_xmlfunc.h
index 637f505e12e..e0356d367bd 100644
--- a/sql/item_xmlfunc.h
+++ b/sql/item_xmlfunc.h
@@ -67,6 +67,7 @@ protected:
return parse(res, cache);
}
};
+ String m_xpath_query; // XPath query text
Item *nodeset_func;
XML xml;
bool get_xml(XML *xml, bool cache= false)