Merge abarkov@bk-internal.mysql.com:/home/bk/mysql-5.1-rpl
into mysql.com:/home/bar/mysql-5.1.b26518 mysql-test/r/xml.result: Auto merged mysql-test/t/xml.test: Auto merged sql/item_xmlfunc.cc: Auto merged
This commit is contained in:
commit
2375c78f4d
@ -891,3 +891,118 @@ test
|
|||||||
select ExtractValue('<a><self>test</self></a>', '/a/self');
|
select ExtractValue('<a><self>test</self></a>', '/a/self');
|
||||||
ExtractValue('<a><self>test</self></a>', '/a/self')
|
ExtractValue('<a><self>test</self></a>', '/a/self')
|
||||||
test
|
test
|
||||||
|
set @i=1;
|
||||||
|
select ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
|
||||||
|
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]')
|
||||||
|
b1
|
||||||
|
set @i=2;
|
||||||
|
select ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
|
||||||
|
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]')
|
||||||
|
b2
|
||||||
|
set @i=NULL;
|
||||||
|
select ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
|
||||||
|
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]')
|
||||||
|
|
||||||
|
CREATE PROCEDURE spxml(xml VARCHAR(128))
|
||||||
|
BEGIN
|
||||||
|
DECLARE c INT;
|
||||||
|
DECLARE i INT DEFAULT 1;
|
||||||
|
SET c= ExtractValue(xml,'count(/a/b)');
|
||||||
|
SET @i= c;
|
||||||
|
WHILE i <= c DO
|
||||||
|
BEGIN
|
||||||
|
SELECT i, @i, ExtractValue(xml,'/a/b[$i]'), ExtractValue(xml,'/a/b[$@i]');
|
||||||
|
SET i= i + 1;
|
||||||
|
SET @i= @i - 1;
|
||||||
|
END;
|
||||||
|
END WHILE;
|
||||||
|
END|
|
||||||
|
call spxml('<a><b>b1</b><b>b2</b><b>b3</b></a>');
|
||||||
|
i @i ExtractValue(xml,'/a/b[$i]') ExtractValue(xml,'/a/b[$@i]')
|
||||||
|
1 3 b1 b3
|
||||||
|
i @i ExtractValue(xml,'/a/b[$i]') ExtractValue(xml,'/a/b[$@i]')
|
||||||
|
2 2 b2 b2
|
||||||
|
i @i ExtractValue(xml,'/a/b[$i]') ExtractValue(xml,'/a/b[$@i]')
|
||||||
|
3 1 b3 b1
|
||||||
|
drop procedure spxml;
|
||||||
|
Multiple matches, but no index specification
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b');
|
||||||
|
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b')
|
||||||
|
b1 b2
|
||||||
|
No matches
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/c');
|
||||||
|
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/c')
|
||||||
|
|
||||||
|
Index out of range
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[-1]');
|
||||||
|
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[-1]')
|
||||||
|
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[10]');
|
||||||
|
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[10]')
|
||||||
|
|
||||||
|
With string-to-number conversion
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["1"]');
|
||||||
|
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["1"]')
|
||||||
|
b1
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["1 and string"]');
|
||||||
|
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["1 and string"]')
|
||||||
|
b1
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect INTEGER value: '1 and string"]'
|
||||||
|
Warning 1292 Truncated incorrect INTEGER value: '1 and string"]'
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["string and 1"]');
|
||||||
|
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["string and 1"]')
|
||||||
|
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect INTEGER value: 'string and 1"]'
|
||||||
|
Warning 1292 Truncated incorrect INTEGER value: 'string and 1"]'
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["string"]');
|
||||||
|
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["string"]')
|
||||||
|
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect INTEGER value: 'string"]'
|
||||||
|
Warning 1292 Truncated incorrect INTEGER value: 'string"]'
|
||||||
|
String-to-number conversion from a user variable
|
||||||
|
SET @i='1';
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
|
||||||
|
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]')
|
||||||
|
b1
|
||||||
|
SET @i='1 and string';
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
|
||||||
|
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]')
|
||||||
|
b1
|
||||||
|
SET @i='string and 1';
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
|
||||||
|
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]')
|
||||||
|
|
||||||
|
SET @i='string';
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
|
||||||
|
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]')
|
||||||
|
|
||||||
|
String-to-number conversion with a CHAR SP variable
|
||||||
|
CREATE PROCEDURE spxml(xml VARCHAR(128), i CHAR(16))
|
||||||
|
BEGIN
|
||||||
|
SELECT ExtractValue(xml,'/a/b[$i]');
|
||||||
|
END|
|
||||||
|
CALL spxml('<a><b>b1</b><b>b2</b></a>', '1');
|
||||||
|
ExtractValue(xml,'/a/b[$i]')
|
||||||
|
b1
|
||||||
|
CALL spxml('<a><b>b1</b><b>b2</b></a>', '1 and string');
|
||||||
|
ExtractValue(xml,'/a/b[$i]')
|
||||||
|
b1
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect INTEGER value: '1 and string '
|
||||||
|
Warning 1292 Truncated incorrect INTEGER value: '1 and string '
|
||||||
|
CALL spxml('<a><b>b1</b><b>b2</b></a>', 'string and 1');
|
||||||
|
ExtractValue(xml,'/a/b[$i]')
|
||||||
|
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect INTEGER value: 'string and 1 '
|
||||||
|
Warning 1292 Truncated incorrect INTEGER value: 'string and 1 '
|
||||||
|
CALL spxml('<a><b>b1</b><b>b2</b></a>', 'string');
|
||||||
|
ExtractValue(xml,'/a/b[$i]')
|
||||||
|
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect INTEGER value: 'string '
|
||||||
|
Warning 1292 Truncated incorrect INTEGER value: 'string '
|
||||||
|
DROP PROCEDURE spxml;
|
||||||
|
@ -451,3 +451,75 @@ select ExtractValue('<a><parent>test</parent></a>', '/a/parent');
|
|||||||
select ExtractValue('<a><preceding>test</preceding></a>', '/a/preceding');
|
select ExtractValue('<a><preceding>test</preceding></a>', '/a/preceding');
|
||||||
select ExtractValue('<a><preceding-sibling>test</preceding-sibling></a>', '/a/preceding-sibling');
|
select ExtractValue('<a><preceding-sibling>test</preceding-sibling></a>', '/a/preceding-sibling');
|
||||||
select ExtractValue('<a><self>test</self></a>', '/a/self');
|
select ExtractValue('<a><self>test</self></a>', '/a/self');
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#26518 XPath and variables problem
|
||||||
|
# Check with user defined variables
|
||||||
|
#
|
||||||
|
set @i=1;
|
||||||
|
select ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
|
||||||
|
set @i=2;
|
||||||
|
select ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
|
||||||
|
set @i=NULL;
|
||||||
|
select ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check variables in a stored procedure - both local and user variables
|
||||||
|
# Make sure that SP and local variables with the same name work together.
|
||||||
|
#
|
||||||
|
DELIMITER |;
|
||||||
|
CREATE PROCEDURE spxml(xml VARCHAR(128))
|
||||||
|
BEGIN
|
||||||
|
DECLARE c INT;
|
||||||
|
DECLARE i INT DEFAULT 1;
|
||||||
|
SET c= ExtractValue(xml,'count(/a/b)');
|
||||||
|
SET @i= c;
|
||||||
|
WHILE i <= c DO
|
||||||
|
BEGIN
|
||||||
|
SELECT i, @i, ExtractValue(xml,'/a/b[$i]'), ExtractValue(xml,'/a/b[$@i]');
|
||||||
|
SET i= i + 1;
|
||||||
|
SET @i= @i - 1;
|
||||||
|
END;
|
||||||
|
END WHILE;
|
||||||
|
END|
|
||||||
|
DELIMITER ;|
|
||||||
|
|
||||||
|
call spxml('<a><b>b1</b><b>b2</b><b>b3</b></a>');
|
||||||
|
drop procedure spxml;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Additional tests for bug#26518
|
||||||
|
--echo Multiple matches, but no index specification
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b');
|
||||||
|
--echo No matches
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/c');
|
||||||
|
--echo Index out of range
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[-1]');
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[10]');
|
||||||
|
--echo With string-to-number conversion
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["1"]');
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["1 and string"]');
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["string and 1"]');
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["string"]');
|
||||||
|
--echo String-to-number conversion from a user variable
|
||||||
|
SET @i='1';
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
|
||||||
|
SET @i='1 and string';
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
|
||||||
|
SET @i='string and 1';
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
|
||||||
|
SET @i='string';
|
||||||
|
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
|
||||||
|
|
||||||
|
--echo String-to-number conversion with a CHAR SP variable
|
||||||
|
DELIMITER |;
|
||||||
|
CREATE PROCEDURE spxml(xml VARCHAR(128), i CHAR(16))
|
||||||
|
BEGIN
|
||||||
|
SELECT ExtractValue(xml,'/a/b[$i]');
|
||||||
|
END|
|
||||||
|
DELIMITER ;|
|
||||||
|
CALL spxml('<a><b>b1</b><b>b2</b></a>', '1');
|
||||||
|
CALL spxml('<a><b>b1</b><b>b2</b></a>', '1 and string');
|
||||||
|
CALL spxml('<a><b>b1</b><b>b2</b></a>', 'string and 1');
|
||||||
|
CALL spxml('<a><b>b1</b><b>b2</b></a>', 'string');
|
||||||
|
DROP PROCEDURE spxml;
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include "my_xml.h"
|
#include "my_xml.h"
|
||||||
|
#include "sp_pcontext.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: future development directions:
|
TODO: future development directions:
|
||||||
@ -2412,21 +2412,78 @@ my_xpath_parse_QName(MY_XPATH *xpath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Scan Variable reference
|
Scan Variable reference
|
||||||
|
|
||||||
SYNOPSYS
|
@details Implements parsing of two syntax structures:
|
||||||
|
|
||||||
[36] VariableReference ::= '$' QName
|
1. Standard XPath syntax [36], for SP variables:
|
||||||
RETURN
|
|
||||||
1 - success
|
VariableReference ::= '$' QName
|
||||||
0 - failure
|
|
||||||
|
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
|
static int
|
||||||
my_xpath_parse_VariableReference(MY_XPATH *xpath)
|
my_xpath_parse_VariableReference(MY_XPATH *xpath)
|
||||||
{
|
{
|
||||||
return my_xpath_parse_term(xpath, MY_XPATH_LEX_DOLLAR) &&
|
LEX_STRING name;
|
||||||
my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user