List:Commits« Previous MessageNext Message »
From:bar Date:May 2 2007 6:42am
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
  1.2481 07/05/02 11:42:04 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.

  sql/item_xmlfunc.cc
    1.27 07/05/02 11:42:00 bar@stripped +66 -9
    Adding variables support:
    - SP variables with standard XPath syntax:  $i
    - User variables with non-standard syntax:  $@i

  mysql-test/t/xml.test
    1.20 07/05/02 11:42:00 bar@stripped +45 -0
    Adding test case

  mysql-test/r/xml.result
    1.22 07/05/02 11:42:00 bar@stripped +49 -0
    Adding test case

# 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-02 11:42:00 +05:00
@@ -884,3 +884,52 @@ 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]')
+

--- 1.19/mysql-test/t/xml.test	2006-12-27 18:14:24 +04:00
+++ 1.20/mysql-test/t/xml.test	2007-05-02 11:42:00 +05:00
@@ -444,3 +444,48 @@ select ExtractValue('<a><parent>test</pa
 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]');

--- 1.26/sql/item_xmlfunc.cc	2007-02-24 14:43:10 +04:00
+++ 1.27/sql/item_xmlfunc.cc	2007-05-02 11:42:00 +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 @@ 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;
 }
 
 
Thread
bk commit into 5.1 tree (bar:1.2481) BUG#26518bar2 May