List:Commits« Previous MessageNext Message »
From:bar Date:May 8 2007 8:32am
Subject:bk commit into 5.1 tree (bar:1.2481) BUG#26518
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of bar. When bar does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-05-08 13:32:29+05:00, bar@stripped +3 -0
  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.

  mysql-test/r/xml.result@stripped, 2007-05-08 13:32:28+05:00, bar@stripped +115 -0
    Adding test case

  mysql-test/t/xml.test@stripped, 2007-05-08 13:32:28+05:00, bar@stripped +72 -0
    Adding test case

  sql/item_xmlfunc.cc@stripped, 2007-05-08 13:32:28+05:00, bar@stripped +66 -9
    Adding variables support:
    - SP variables with standard XPath syntax:  $i
    - User variables with non-standard syntax:  $@i

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	bar
# Host:	bar.myoffice.izhnet.ru
# Root:	/home/bar/mysql-5.1.b26518

--- 1.21/mysql-test/r/xml.result	2007-01-22 13:28:51 +04:00
+++ 1.22/mysql-test/r/xml.result	2007-05-08 13:32:28 +05:00
@@ -884,3 +884,118 @@
 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;

--- 1.19/mysql-test/t/xml.test	2006-12-27 18:14:24 +04:00
+++ 1.20/mysql-test/t/xml.test	2007-05-08 13:32:28 +05:00
@@ -444,3 +444,75 @@
 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;

--- 1.26/sql/item_xmlfunc.cc	2007-02-24 14:43:10 +04:00
+++ 1.27/sql/item_xmlfunc.cc	2007-05-08 13:32:28 +05:00
@@ -19,7 +19,7 @@
 
 #include "mysql_priv.h"
 #include "my_xml.h"
-
+#include "sp_pcontext.h"
 
 /*
   TODO: future development directions:
@@ -2412,21 +2412,78 @@
 }
 
 
-/*
+/**
   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;
 }
 
 
Thread
bk commit into 5.1 tree (bar:1.2481) BUG#26518bar8 May