List:Commits« Previous MessageNext Message »
From:Alexey Kopytov Date:December 14 2006 5:58pm
Subject:bk commit into 5.0 tree (kaa:1.2334) BUG#24117
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of kaa. When kaa 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, 2006-12-14 20:58:07+03:00, kaa@stripped +6 -0
  Fix for bug #24117 "server crash on a FETCH with a cursor on a table which is not in the table cache"
  
  Problem:
  When creating a temporary field for a temporary table in create_tmp_field_from_field(), a resulting field is created as an exact copy of an original one (in Field::new_field()). However, Field_enum and Field_set contain a pointer (typelib) to memory allocated in the parent table's MEM_ROOT, which under some circumstances may be deallocated later by the time a temporary table is used.
  
  Solution:
  Override the new_field() method for Field_enum and Field_set and create a separate copy of the typelib structure in there.

  include/typelib.h@stripped, 2006-12-14 20:58:03+03:00, kaa@stripped +3 -0
    Added copy_typelib() declaration

  mysql-test/r/sp.result@stripped, 2006-12-14 20:58:03+03:00, kaa@stripped +16 -0
    Added a testcase for bug #24117 "server crash on a FETCH with a cursor on a table which is not in the table cache"

  mysql-test/t/sp.test@stripped, 2006-12-14 20:58:04+03:00, kaa@stripped +24 -0
    Added a testcase for bug #24117 "server crash on a FETCH with a cursor on a table which is not in the table cache"

  mysys/typelib.c@stripped, 2006-12-14 20:58:04+03:00, kaa@stripped +51 -0
    Added copy_typelib() definition

  sql/field.cc@stripped, 2006-12-14 20:58:04+03:00, kaa@stripped +10 -0
    Create a copy of the internal 'typelib' structure when copying Field_enum of Field_set objects.

  sql/field.h@stripped, 2006-12-14 20:58:04+03:00, kaa@stripped +1 -0
    Override new_field method in Field_enum (and Field_set) to copy the typelib structure.

# 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:	kaa
# Host:	polly.local
# Root:	/tmp/maint/bug24117/my50-bug24117

--- 1.13/mysys/typelib.c	2006-12-14 20:58:14 +03:00
+++ 1.14/mysys/typelib.c	2006-12-14 20:58:14 +03:00
@@ -119,3 +119,54 @@ const char *get_type(TYPELIB *typelib, u
     return(typelib->type_names[nr]);
   return "?";
 }
+
+
+/*
+  Create a copy of a specified TYPELIB structure.
+
+  SYNOPSIS
+    copy_typelib()
+    root	pointer to a MEM_ROOT object for allocations
+    from	pointer to a source TYPELIB structure
+
+  RETURN
+    pointer to the new TYPELIB structure on successful copy, or
+    NULL otherwise
+*/
+
+TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from)
+{
+  TYPELIB *to;
+  uint i;
+
+  if (!from)
+    return NULL;
+
+  if (!(to= (TYPELIB*) alloc_root(root, sizeof(TYPELIB))))
+    return NULL;
+
+  if (!(to->type_names= (const char **)
+        alloc_root(root, (sizeof(char *) + sizeof(int)) * (from->count + 1))))
+    return NULL;
+  to->type_lengths= (unsigned int *)(to->type_names + from->count + 1);
+  to->count= from->count;
+  if (from->name)
+  {
+    if (!(to->name= strdup_root(root, from->name)))
+      return NULL;
+  }
+  else
+    to->name= NULL;
+
+  for (i= 0; i < from->count; i++)
+  {
+    if (!(to->type_names[i]= strmake_root(root, from->type_names[i],
+                                          from->type_lengths[i])))
+      return NULL;
+    to->type_lengths[i]= from->type_lengths[i];
+  }
+  to->type_names[to->count]= NULL;
+  to->type_lengths[to->count]= 0;
+
+  return to;
+}

--- 1.328/sql/field.cc	2006-12-14 20:58:14 +03:00
+++ 1.329/sql/field.cc	2006-12-14 20:58:14 +03:00
@@ -7672,6 +7672,16 @@ void Field_enum::sql_type(String &res) c
 }
 
 
+Field *Field_enum::new_field(MEM_ROOT *root, struct st_table *new_table,
+                             bool keep_type)
+{
+  Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
+  if (res)
+    res->typelib= copy_typelib(root, typelib);
+  return res;
+}
+
+
 /*
    set type.
    This is a string which can have a collection of different values.

--- 1.189/sql/field.h	2006-12-14 20:58:14 +03:00
+++ 1.190/sql/field.h	2006-12-14 20:58:14 +03:00
@@ -1277,6 +1277,7 @@ public:
   {
       flags|=ENUM_FLAG;
   }
+  Field *new_field(MEM_ROOT *root, struct st_table *new_table, bool keep_type);
   enum_field_types type() const { return FIELD_TYPE_STRING; }
   enum Item_result cmp_type () const { return INT_RESULT; }
   enum Item_result cast_to_int_type () const { return INT_RESULT; }

--- 1.3/include/typelib.h	2006-12-14 20:58:14 +03:00
+++ 1.4/include/typelib.h	2006-12-14 20:58:14 +03:00
@@ -18,6 +18,8 @@
 #ifndef _typelib_h
 #define _typelib_h
 
+#include "my_alloc.h"
+
 typedef struct st_typelib {	/* Different types saved here */
   unsigned int count;		/* How many types */
   const char *name;		/* Name of typelib */
@@ -28,6 +30,7 @@ typedef struct st_typelib {	/* Different
 extern int find_type(char *x,TYPELIB *typelib,unsigned int full_name);
 extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
 extern const char *get_type(TYPELIB *typelib,unsigned int nr);
+extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from);
 
 extern TYPELIB sql_protocol_typelib;
 

--- 1.216/mysql-test/r/sp.result	2006-12-14 20:58:14 +03:00
+++ 1.217/mysql-test/r/sp.result	2006-12-14 20:58:14 +03:00
@@ -5708,4 +5708,20 @@ DROP TABLE bug23760, bug23760_log|
 DROP PROCEDURE bug23760_update_log|
 DROP PROCEDURE bug23760_test_row_count|
 DROP FUNCTION bug23760_rc_test|
+DROP PROCEDURE IF EXISTS bug24117|
+DROP TABLE IF EXISTS t3|
+CREATE TABLE t3(c1 ENUM('abc'))|
+INSERT INTO t3 VALUES('abc')|
+CREATE PROCEDURE bug24117()
+BEGIN
+DECLARE t3c1 ENUM('abc');
+DECLARE mycursor CURSOR FOR SELECT c1 FROM t3;
+OPEN mycursor;
+FLUSH TABLES;
+FETCH mycursor INTO t3c1;
+CLOSE mycursor;
+END|
+CALL bug24117()|
+DROP PROCEDURE bug24117|
+DROP TABLE t3|
 drop table t1,t2;

--- 1.206/mysql-test/t/sp.test	2006-12-14 20:58:14 +03:00
+++ 1.207/mysql-test/t/sp.test	2006-12-14 20:58:14 +03:00
@@ -6663,6 +6663,30 @@ DROP PROCEDURE bug23760_test_row_count|
 DROP FUNCTION bug23760_rc_test|
 
 #
+# BUG#24117: server crash on a FETCH with a cursor on a table which is not in
+#            the table cache
+#
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS bug24117|
+DROP TABLE IF EXISTS t3|
+--enable_warnings
+CREATE TABLE t3(c1 ENUM('abc'))|
+INSERT INTO t3 VALUES('abc')|
+CREATE PROCEDURE bug24117()
+BEGIN
+  DECLARE t3c1 ENUM('abc');
+  DECLARE mycursor CURSOR FOR SELECT c1 FROM t3;
+  OPEN mycursor;
+  FLUSH TABLES;
+  FETCH mycursor INTO t3c1;
+  CLOSE mycursor;
+END|
+CALL bug24117()|
+DROP PROCEDURE bug24117|
+DROP TABLE t3|
+
+#
 # NOTE: The delimiter is `|`, and not `;`. It is changed to `;`
 #       at the end of the file!
 #
Thread
bk commit into 5.0 tree (kaa:1.2334) BUG#24117Alexey Kopytov14 Dec