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');
|
||||
ExtractValue('<a><self>test</self></a>', '/a/self')
|
||||
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-sibling>test</preceding-sibling></a>', '/a/preceding-sibling');
|
||||
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 "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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user