List:Internals« Previous MessageNext Message »
From:antony Date:April 20 2005 5:09pm
Subject:bk commit into 5.0 tree (acurtis:1.1856) BUG#9775
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of acurtis. When acurtis 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.1856 05/04/20 18:08:42 acurtis@stripped +5 -0
  Bug#9775 - Stored procedures: crash if create function that returns enum or set
    Fix bug and implement return type casting.

  sql/sp_head.cc
    1.128 05/04/20 18:08:28 acurtis@stripped +6 -2
    Bug#9775
      missing initialiation for type_lengths in sp_head::create_typelib()

  sql/item_func.h
    1.106 05/04/20 18:08:27 acurtis@stripped +17 -41
    Bug#9775
      results for Item_func_sp pass through a Field of the return type.
      new method Item_func_sp::execute(Field **)

  sql/item_func.cc
    1.181 05/04/20 18:08:27 acurtis@stripped +48 -14
    Bug#9775
      new method Item_func_sp::execute(Field **)
      some optimizations.

  mysql-test/t/sp.test
    1.111 05/04/20 18:08:27 acurtis@stripped +22 -1
    Bug#9775
      Test for bug + feature
    Fix previous tests

  mysql-test/r/sp.result
    1.116 05/04/20 18:08:26 acurtis@stripped +24 -3
    Bug#9775
      Test for bug + feature
    Fix previous tests

# 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:	acurtis
# Host:	ltantony.xiphis.org
# Root:	/.amd_mnt/bk.anubis/host/work-acurtis/bug9102

--- 1.180/sql/item_func.cc	2005-03-28 10:15:07 +01:00
+++ 1.181/sql/item_func.cc	2005-04-20 18:08:27 +01:00
@@ -4461,7 +4461,7 @@
 
 
 Item_func_sp::Item_func_sp(sp_name *name)
-  :Item_func(), m_name(name), m_sp(NULL)
+  :Item_func(), m_name(name), m_sp(NULL), result_field(NULL)
 {
   maybe_null= 1;
   m_name->init_qname(current_thd);
@@ -4470,7 +4470,7 @@
 
 
 Item_func_sp::Item_func_sp(sp_name *name, List<Item> &list)
-  :Item_func(list), m_name(name), m_sp(NULL)
+  :Item_func(list), m_name(name), m_sp(NULL), result_field(NULL)
 {
   maybe_null= 1;
   m_name->init_qname(current_thd);
@@ -4527,6 +4527,29 @@
 
 
 int
+Item_func_sp::execute(Field **flp)
+{
+  Item *it;
+  Field *f;
+  if (execute(&it))
+  {
+    null_value= 1;
+    return 1;
+  }
+  if (!(f= *flp))
+  {
+    *flp= f= sp_result_field();
+    f->move_field((f->pack_length() > sizeof(result_buf)) ? 
+                  sql_alloc(f->pack_length()) : result_buf);
+    f->null_ptr= (uchar *)&null_value;
+    f->null_bit= 1;
+  }
+  it->save_in_field(f, 1);
+  return f->is_null();
+}
+
+
+int
 Item_func_sp::execute(Item **itp)
 {
   DBUG_ENTER("Item_func_sp::execute");
@@ -4601,6 +4624,8 @@
   Field *field= 0;
   DBUG_ENTER("Item_func_sp::field_type");
 
+  if (result_field)
+    DBUG_RETURN(result_field->type());
   if (! m_sp)
     m_sp= sp_find_function(current_thd, m_name, TRUE); // cache only
   if ((field= sp_result_field()))
@@ -4621,6 +4646,8 @@
   DBUG_ENTER("Item_func_sp::result_type");
   DBUG_PRINT("info", ("m_sp = %p", m_sp));
 
+  if (result_field)
+    DBUG_RETURN(result_field->result_type());
   if (! m_sp)
     m_sp= sp_find_function(current_thd, m_name, TRUE); // cache only
   if ((field= sp_result_field()))
@@ -4636,8 +4663,16 @@
 void
 Item_func_sp::fix_length_and_dec()
 {
+  Field *field= result_field;
   DBUG_ENTER("Item_func_sp::fix_length_and_dec");
 
+  if (result_field)
+  {
+    decimals= result_field->decimals();
+    max_length= result_field->representation_length();
+    DBUG_VOID_RETURN;
+  }
+
   if (! m_sp)
     m_sp= sp_find_function(current_thd, m_name, TRUE); // cache only
   if (! m_sp)
@@ -4646,29 +4681,28 @@
   }
   else
   {
-    switch (result_type()) {
+    if (!field)
+      field= sp_result_field();
+      
+    decimals= field->decimals();
+    max_length= field->representation_length();
+    
+    switch (field->result_type()) {
     case STRING_RESULT:
       maybe_null= 1;
-      max_length= MAX_BLOB_WIDTH;
-      break;
     case REAL_RESULT:
-      decimals= NOT_FIXED_DEC;
-      max_length= float_length(decimals);
-      break;
     case INT_RESULT:
-      decimals= 0;
-      max_length= 21;
-      break;
     case DECIMAL_RESULT:
-      // TODO: where to find real precision and scale?
-      decimals= min(DECIMAL_MAX_LENGTH / 2, NOT_FIXED_DEC - 1);
-      max_length= DECIMAL_MAX_LENGTH;
+      break;
     case ROW_RESULT:
     default:
       // This case should never be chosen
       DBUG_ASSERT(0);
       break;
     }
+    
+    if (field != result_field)
+      delete field;    
   }
   DBUG_VOID_RETURN;
 }

--- 1.105/sql/item_func.h	2005-04-19 10:50:59 +01:00
+++ 1.106/sql/item_func.h	2005-04-20 18:08:27 +01:00
@@ -1283,8 +1283,11 @@
   sp_name *m_name;
   mutable sp_head *m_sp;
   TABLE *dummy_table;
+  Field *result_field;
+  char result_buf[64];
 
   int execute(Item **itp);
+  int execute(Field **flp);
   Field *sp_result_field(void) const;
 
 public:
@@ -1296,6 +1299,12 @@
   virtual ~Item_func_sp()
   {}
 
+  void cleanup()
+  {
+    Item_func::cleanup();
+    result_field= NULL;
+  }
+
   const char *func_name() const;
 
   enum enum_field_types field_type() const;
@@ -1308,63 +1317,30 @@
 
   longlong val_int()
   {
-    Item *it;
-    longlong l;
-
-    if (execute(&it))
-    {
-      null_value= 1;
+    if (execute(&result_field))
       return 0LL;
-    }
-    l= it->val_int();
-    null_value= it->null_value;
-    return l;
+    return result_field->val_int();   
   }
 
   double val_real()
   {
-    Item *it;
-    double d;
-
-    if (execute(&it))
-    {
-      null_value= 1;
+    if (execute(&result_field))
       return 0.0;
-    }
-    d= it->val_real();
-    null_value= it->null_value;
-    return d;
+    return result_field->val_real();
   }
 
   my_decimal *val_decimal(my_decimal *dec_buf)
   {
-    Item *it;
-    my_decimal *result;
-
-    if (execute(&it))
-    {
-      null_value= 1;
+    if (execute(&result_field))
       return NULL;
-    }
-    result= it->val_decimal(dec_buf);
-    null_value= it->null_value;
-    return result;
+    return result_field->val_decimal(dec_buf);
   }
 
-
   String *val_str(String *str)
   {
-    Item *it;
-    String *s;
-
-    if (execute(&it))
-    {
-      null_value= 1;
+    if (execute(&result_field))
       return NULL;
-    }
-    s= it->val_str(str);
-    null_value= it->null_value;
-    return s;
+    return result_field->val_str(str);
   }
 
   void fix_length_and_dec();

--- 1.115/mysql-test/r/sp.result	2005-04-19 10:50:58 +01:00
+++ 1.116/mysql-test/r/sp.result	2005-04-20 18:08:26 +01:00
@@ -2960,14 +2960,35 @@
 drop function bug9902|
 drop function if exists bug9102|
 create function bug9102() returns blob return 'a'|
-select bug9102();
-drop function bug9102|
+select bug9102()|
 bug9102()
 a
-drop procedure if exists bug7648|
+drop function bug9102|
+drop function if exists bug7648|
 create function bug7648() returns bit(8) return 'a'|
 select bug7648()|
 bug7648()
 a
 drop function bug7648|
+drop function if exists bug9775|
+create function bug9775(v1 char(1)) returns enum('a','b') return v1|
+select bug9775('a'),bug9775('b'),bug9775('c')|
+bug9775('a')	bug9775('b')	bug9775('c')
+a	b	
+drop function bug9775|
+create function bug9775(v1 int) returns enum('a','b') return v1|
+select bug9775(1),bug9775(2),bug9775(3)|
+bug9775(1)	bug9775(2)	bug9775(3)
+a	b	
+drop function bug9775|
+create function bug9775(v1 char(1)) returns set('a','b') return v1|
+select bug9775('a'),bug9775('b'),bug9775('a,b'),bug9775('c')|
+bug9775('a')	bug9775('b')	bug9775('a,b')	bug9775('c')
+a	b	a,b	
+drop function bug9775|
+create function bug9775(v1 int) returns set('a','b') return v1|
+select bug9775(1),bug9775(2),bug9775(3),bug9775(4)|
+bug9775(1)	bug9775(2)	bug9775(3)	bug9775(4)
+a	b	a,b	
+drop function bug9775|
 drop table t1,t2;

--- 1.110/mysql-test/t/sp.test	2005-04-19 10:50:59 +01:00
+++ 1.111/mysql-test/t/sp.test	2005-04-20 18:08:27 +01:00
@@ -3643,11 +3643,32 @@
 # BUG#7648: Stored procedure crash when invoking a function that returns a bit
 #
 --disable_warnings
-drop procedure if exists bug7648|
+drop function if exists bug7648|
 --enable_warnings
 create function bug7648() returns bit(8) return 'a'|
 select bug7648()|
 drop function bug7648|
+
+
+#
+# BUG#9775: crash if create function that returns enum or set
+#
+--disable_warnings
+drop function if exists bug9775|
+--enable_warnings
+create function bug9775(v1 char(1)) returns enum('a','b') return v1|
+select bug9775('a'),bug9775('b'),bug9775('c')|
+drop function bug9775|
+create function bug9775(v1 int) returns enum('a','b') return v1|
+select bug9775(1),bug9775(2),bug9775(3)|
+drop function bug9775|
+
+create function bug9775(v1 char(1)) returns set('a','b') return v1|
+select bug9775('a'),bug9775('b'),bug9775('a,b'),bug9775('c')|
+drop function bug9775|
+create function bug9775(v1 int) returns set('a','b') return v1|
+select bug9775(1),bug9775(2),bug9775(3),bug9775(4)|
+drop function bug9775|
 
 
 #

--- 1.127/sql/sp_head.cc	2005-04-19 09:09:11 +01:00
+++ 1.128/sql/sp_head.cc	2005-04-20 18:08:28 +01:00
@@ -378,8 +378,9 @@
     result->count= src->elements;
     result->name= "";
     if (!(result->type_names=(const char **)
-          alloc_root(mem_root,sizeof(char *)*(result->count+1))))
+          alloc_root(mem_root,(sizeof(char *)+sizeof(int))*(result->count+1))))
       return 0;
+    result->type_lengths= (unsigned int *)(result->type_names + result->count+1);
     List_iterator<String> it(*src);
     String conv, *tmp;
     uint32 dummy;
@@ -397,8 +398,10 @@
         result->type_names[i]= buf;
         result->type_lengths[i]= conv.length();
       }
-      else
+      else {
         result->type_names[i]= strdup_root(mem_root, tmp->c_ptr());
+        result->type_lengths[i]= tmp->length();
+      }
 
       // Strip trailing spaces.
       uint lengthsp= cs->cset->lengthsp(cs, result->type_names[i],
@@ -407,6 +410,7 @@
       ((uchar *)result->type_names[i])[lengthsp]= '\0';
     }
     result->type_names[result->count]= 0;
+    result->type_lengths[result->count]= 0;
   }
   return result;
 }
Thread
bk commit into 5.0 tree (acurtis:1.1856) BUG#9775antony20 Apr