List:Commits« Previous MessageNext Message »
From:Bjorn Munch Date:January 17 2011 9:29am
Subject:bzr commit into mysql-5.1-mtr branch (bjorn.munch:2969)
View as plain text  
#At file:///home/bm136801/my/merge-51/ based on revid:bjorn.munch@stripped

 2969 Bjorn Munch	2011-01-17 [merge]
      merge from 5.1 main

    modified:
      client/mysqladmin.cc
      client/mysqldump.c
      client/mysqlslap.c
      configure.in
      mysql-test/include/rpl_start_server.inc
      mysql-test/include/rpl_stop_server.inc
      mysql-test/r/client_xml.result
      mysql-test/r/func_str.result
      mysql-test/r/gis.result
      mysql-test/r/mysqladmin.result
      mysql-test/r/mysqlbinlog_row_big.result
      mysql-test/r/mysqldump.result
      mysql-test/t/func_str.test
      mysql-test/t/gis.test
      mysql-test/t/mysqladmin.test
      mysql-test/t/mysqlbinlog_row_big.test
      mysql-test/t/mysqldump.test
      sql/item_geofunc.h
      sql/item_strfunc.cc
      sql/item_strfunc.h
      sql/sql_string.cc
      sql/sql_string.h
=== modified file 'client/mysqladmin.cc'
--- a/client/mysqladmin.cc	2010-06-10 20:16:43 +0000
+++ b/client/mysqladmin.cc	2011-01-15 20:34:08 +0000
@@ -416,6 +416,9 @@ int main(int argc,char *argv[])
 
       if (interval)                             /* --sleep=interval given */
       {
+        if (opt_count_iterations && --nr_iterations == 0)
+          break;
+
         /*
           If connection was dropped (unintentionally, or due to SHUTDOWN),
           re-establish it if --wait ("retry-connect") was given and user

=== modified file 'client/mysqldump.c'
--- a/client/mysqldump.c	2010-06-10 20:16:43 +0000
+++ b/client/mysqldump.c	2011-01-14 14:20:34 +0000
@@ -2247,6 +2247,15 @@ static uint get_table_structure(char *ta
   const char *insert_option;
   char	     name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
   char       table_buff2[NAME_LEN*2+3], query_buff[QUERY_LENGTH];
+  const char *show_fields_stmt= "SELECT `COLUMN_NAME` AS `Field`, "
+                                "`COLUMN_TYPE` AS `Type`, "
+                                "`IS_NULLABLE` AS `Null`, "
+                                "`COLUMN_KEY` AS `Key`, "
+                                "`COLUMN_DEFAULT` AS `Default`, "
+                                "`EXTRA` AS `Extra`, "
+                                "`COLUMN_COMMENT` AS `Comment` "
+                                "FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE "
+                                "TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s'";
   FILE       *sql_file= md_result_file;
   int        len;
   MYSQL_RES  *result;
@@ -2514,8 +2523,8 @@ static uint get_table_structure(char *ta
     verbose_msg("%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n",
                 my_progname, mysql_error(mysql));
 
-    my_snprintf(query_buff, sizeof(query_buff), "show fields from %s",
-                result_table);
+    my_snprintf(query_buff, sizeof(query_buff), show_fields_stmt, db, table);
+
     if (mysql_query_with_error_report(mysql, &result, query_buff))
       DBUG_RETURN(0);
 

=== modified file 'client/mysqlslap.c'
--- a/client/mysqlslap.c	2010-06-10 20:16:43 +0000
+++ b/client/mysqlslap.c	2011-01-13 10:26:42 +0000
@@ -1519,7 +1519,12 @@ generate_primary_key_list(MYSQL *mysql,
       exit(1);
     }
 
-    result= mysql_store_result(mysql);
+    if (!(result= mysql_store_result(mysql)))
+    {
+      fprintf(stderr, "%s: Error when storing result: %d %s\n",
+              my_progname, mysql_errno(mysql), mysql_error(mysql));
+      exit(1);
+    }
     primary_keys_number_of= mysql_num_rows(result);
 
     /* So why check this? Blackhole :) */
@@ -1891,10 +1896,15 @@ limit_not_met:
       {
         if (mysql_field_count(mysql))
         {
-          result= mysql_store_result(mysql);
-          while ((row = mysql_fetch_row(result)))
-            counter++;
-          mysql_free_result(result);
+          if (!(result= mysql_store_result(mysql)))
+            fprintf(stderr, "%s: Error when storing result: %d %s\n",
+                    my_progname, mysql_errno(mysql), mysql_error(mysql));
+          else
+          {
+            while ((row= mysql_fetch_row(result)))
+              counter++;
+            mysql_free_result(result);
+          }
         }
       } while(mysql_next_result(mysql) == 0);
       queries++;

=== modified file 'configure.in'
--- a/configure.in	2010-12-28 23:47:05 +0000
+++ b/configure.in	2011-01-13 08:59:11 +0000
@@ -12,7 +12,7 @@ dnl
 dnl When changing the major version number please also check the switch
 dnl statement in mysqlbinlog::check_master_version().  You may also need
 dnl to update version.c in ndb.
-AC_INIT([MySQL Server], [5.1.55], [], [mysql])
+AC_INIT([MySQL Server], [5.1.56], [], [mysql])
 
 AC_CONFIG_SRCDIR([sql/mysqld.cc])
 AC_CANONICAL_SYSTEM

=== modified file 'mysql-test/include/rpl_start_server.inc'
--- a/mysql-test/include/rpl_start_server.inc	2010-12-19 17:07:28 +0000
+++ b/mysql-test/include/rpl_start_server.inc	2011-01-14 10:33:12 +0000
@@ -45,7 +45,15 @@ if ($rpl_server_parameters)
 --source include/rpl_connection.inc
 
 # Write file to make mysql-test-run.pl start up the server again
---exec echo "$_rpl_start_server_command" > $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect
+--let WRITE_TO_FILE= $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect
+--let WRITE_TO_VAR= $_rpl_start_server_command
+perl;
+my $file= $ENV{'WRITE_TO_FILE'};
+my $var= $ENV{'WRITE_TO_VAR'};
+open WRITE_FILE, ">> $file" or die "Error opening $file: $!";
+print WRITE_FILE $var, "\n" or die "Error appending to $file: $!";
+close WRITE_FILE or die "Error closing $file: $!";
+EOF
 
 --source include/rpl_reconnect.inc
 

=== modified file 'mysql-test/include/rpl_stop_server.inc'
--- a/mysql-test/include/rpl_stop_server.inc	2010-12-19 17:07:28 +0000
+++ b/mysql-test/include/rpl_stop_server.inc	2011-01-14 10:33:12 +0000
@@ -44,7 +44,9 @@ if ($rpl_debug)
 
 # Write file to make mysql-test-run.pl expect the "crash", but don't start
 # it until it's told to
---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect
+--append_file $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect
+wait
+EOF
 
 # Send shutdown to the connected server and give
 # it 10 seconds to die before zapping it

=== modified file 'mysql-test/r/client_xml.result'
--- a/mysql-test/r/client_xml.result	2008-07-18 12:00:45 +0000
+++ b/mysql-test/r/client_xml.result	2011-01-14 14:20:34 +0000
@@ -21,9 +21,9 @@ insert into t1 values (1, 2, 'a&b a<b a>
 <mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <database name="test">
 	<table_structure name="t1">
-		<field Field="a&amp;b" Type="int(11)" Null="YES" Key="" Extra="" />
-		<field Field="a&lt;b" Type="int(11)" Null="YES" Key="" Extra="" />
-		<field Field="a&gt;b" Type="text" Null="YES" Key="" Extra="" />
+		<field Field="a&amp;b" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
+		<field Field="a&lt;b" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
+		<field Field="a&gt;b" Type="text" Null="YES" Key="" Extra="" Comment="" />
 	</table_structure>
 	<table_data name="t1">
 	<row>

=== modified file 'mysql-test/r/func_str.result'
--- a/mysql-test/r/func_str.result	2010-12-14 16:08:25 +0000
+++ b/mysql-test/r/func_str.result	2011-01-13 07:57:15 +0000
@@ -2612,4 +2612,20 @@ CONVERT(('' IN (REVERSE(CAST(('') AS DEC
 1
 Warnings:
 Warning	1292	Truncated incorrect DECIMAL value: ''
+# 
+# Bug#58165: "my_empty_string" gets modified and causes LOAD DATA to fail
+# and other crashes
+#
+CREATE TABLE t1 ( a TEXT );
+SELECT 'aaaaaaaaaaaaaa' INTO OUTFILE 'bug58165.txt';
+SELECT insert( substring_index( 'a', 'a', 'b' ), 1, 0, 'x' );
+insert( substring_index( 'a', 'a', 'b' ), 1, 0, 'x' )
+x
+Warnings:
+Warning	1292	Truncated incorrect INTEGER value: 'b'
+LOAD DATA INFILE 'bug58165.txt' INTO TABLE t1;
+SELECT * FROM t1;
+a
+aaaaaaaaaaaaaa
+DROP TABLE t1;
 End of 5.1 tests

=== modified file 'mysql-test/r/gis.result'
--- a/mysql-test/r/gis.result	2010-09-09 09:40:17 +0000
+++ b/mysql-test/r/gis.result	2011-01-12 13:02:41 +0000
@@ -1014,4 +1014,12 @@ SET @a=0x0000000003000000010000000000000
 SET @a=POLYFROMWKB(@a);
 SET @a=0x00000000030000000000000000000000000000000000144000000000000014400000000000001840000000000000184000000000000014400000000000001440;
 SET @a=POLYFROMWKB(@a);
+create table t1(a polygon NOT NULL)engine=myisam;
+insert into t1 values (geomfromtext("point(0 1)"));
+insert into t1 values (geomfromtext("point(1 0)"));
+select * from (select polygon(t1.a) as p from t1 order by t1.a) d;
+p
+NULL
+NULL
+drop table t1;
 End of 5.1 tests

=== modified file 'mysql-test/r/mysqladmin.result'
--- a/mysql-test/r/mysqladmin.result	2006-11-10 12:25:10 +0000
+++ b/mysql-test/r/mysqladmin.result	2011-01-15 20:34:08 +0000
@@ -2,3 +2,11 @@ mysqld is alive
 mysqladmin: unknown variable 'database=db1'
 Warning: mysqladmin: unknown variable 'loose-database=db2'
 mysqld is alive
+#
+# Bug#58221 : mysqladmin --sleep=x --count=x keeps looping
+#
+# Executing mysqladmin with --sleep=1 and --count=2.
+# Done.
+# Displaying the output :
+mysqld is alive
+mysqld is alive

=== modified file 'mysql-test/r/mysqlbinlog_row_big.result'
--- a/mysql-test/r/mysqlbinlog_row_big.result	2009-04-02 22:34:18 +0000
+++ b/mysql-test/r/mysqlbinlog_row_big.result	2011-01-12 19:32:45 +0000
@@ -36,8 +36,8 @@ c1 LONGTEXT
 #
 # Insert some big rows.
 #
-256MB
-INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 16777216));
+64MB
+INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 4194304));
 affected rows: 1
 32MB
 INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 2097152));
@@ -53,7 +53,7 @@ affected rows: 1
 # Do not display the column value itself, just its length.
 #
 SELECT LENGTH(c1) FROM t1;
-LENGTH(c1)	268435456
+LENGTH(c1)	67108864
 LENGTH(c1)	33554432
 LENGTH(c1)	4194304
 LENGTH(c1)	524288
@@ -69,7 +69,7 @@ info: Rows matched: 4  Changed: 4  Warni
 # Do not display the column value itself, just its length.
 #
 SELECT LENGTH(c1) FROM t1;
-LENGTH(c1)	536870912
+LENGTH(c1)	134217728
 LENGTH(c1)	1048576
 LENGTH(c1)	67108864
 LENGTH(c1)	8388608

=== modified file 'mysql-test/r/mysqldump.result'
--- a/mysql-test/r/mysqldump.result	2010-05-06 20:41:37 +0000
+++ b/mysql-test/r/mysqldump.result	2011-01-14 14:20:34 +0000
@@ -14,7 +14,7 @@ INSERT INTO t1 VALUES (1), (2);
 <mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <database name="test">
 	<table_structure name="t1">
-		<field Field="a" Type="int(11)" Null="YES" Key="MUL" Extra="" />
+		<field Field="a" Type="int(11)" Null="YES" Key="MUL" Extra="" Comment="" />
 		<key Table="t1" Non_unique="1" Key_name="a" Seq_in_index="1" Column_name="a" Collation="A" Null="YES" Index_type="BTREE" Comment="" />
 	</table_structure>
 	<table_data name="t1">
@@ -150,9 +150,9 @@ INSERT INTO t1 VALUES (1, "test", "tes")
 <mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <database name="test">
 	<table_structure name="t1">
-		<field Field="a" Type="int(11)" Null="YES" Key="" Extra="" />
-		<field Field="b" Type="text" Null="YES" Key="" Extra="" />
-		<field Field="c" Type="varchar(3)" Null="YES" Key="" Extra="" />
+		<field Field="a" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
+		<field Field="b" Type="text" Null="YES" Key="" Extra="" Comment="" />
+		<field Field="c" Type="varchar(3)" Null="YES" Key="" Extra="" Comment="" />
 	</table_structure>
 	<table_data name="t1">
 	<row>
@@ -178,7 +178,7 @@ INSERT INTO t1 VALUES ("1\""), ("\"2");
 <mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <database name="test">
 	<table_structure name="t1">
-		<field Field="a&quot;b&quot;" Type="char(2)" Null="YES" Key="" Extra="" />
+		<field Field="a&quot;b&quot;" Type="char(2)" Null="YES" Key="" Extra="" Comment="" />
 	</table_structure>
 	<table_data name="t1">
 	<row>
@@ -1612,10 +1612,10 @@ CREATE TABLE `t2` (
 <mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <database name="mysqldump_test_db">
 	<table_structure name="t1">
-		<field Field="a" Type="int(11)" Null="YES" Key="" Extra="" />
+		<field Field="a" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
 	</table_structure>
 	<table_structure name="t2">
-		<field Field="a" Type="int(11)" Null="YES" Key="" Extra="" />
+		<field Field="a" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
 	</table_structure>
 </database>
 </mysqldump>
@@ -1623,10 +1623,10 @@ CREATE TABLE `t2` (
 <mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <database name="mysqldump_test_db">
 	<table_structure name="t1">
-		<field Field="a" Type="int(11)" Null="YES" Key="" Extra="" />
+		<field Field="a" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
 	</table_structure>
 	<table_structure name="t2">
-		<field Field="a" Type="int(11)" Null="YES" Key="" Extra="" />
+		<field Field="a" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
 	</table_structure>
 </database>
 </mysqldump>
@@ -3644,8 +3644,8 @@ INSERT INTO t1 VALUES(1,0xff00fef0);
 <mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <database name="test">
 	<table_structure name="t1">
-		<field Field="f1" Type="int(10)" Null="YES" Key="" Extra="" />
-		<field Field="data" Type="mediumblob" Null="YES" Key="" Extra="" />
+		<field Field="f1" Type="int(10)" Null="YES" Key="" Extra="" Comment="" />
+		<field Field="data" Type="mediumblob" Null="YES" Key="" Extra="" Comment="" />
 	</table_structure>
 	<table_data name="t1">
 	<row>
@@ -4576,5 +4576,20 @@ LENGTH(a)
 800
 DROP TABLE t1, t2;
 #
+# Bug #13618 : mysqldump --xml ommit comment on table field
+#
+CREATE TABLE `comment_table` (i INT COMMENT 'FIELD COMMENT') COMMENT = 'TABLE COMMENT';
+<?xml version="1.0"?>
+<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+<database name="test">
+	<table_structure name="comment_table">
+		<field Field="i" Type="int(11)" Null="YES" Key="" Extra="" Comment="FIELD COMMENT" />
+	</table_structure>
+	<table_data name="comment_table">
+	</table_data>
+</database>
+</mysqldump>
+DROP TABLE `comment_table`;
+#
 # End of 5.1 tests
 #

=== modified file 'mysql-test/t/func_str.test'
--- a/mysql-test/t/func_str.test	2010-12-14 16:08:25 +0000
+++ b/mysql-test/t/func_str.test	2011-01-13 07:57:15 +0000
@@ -1369,4 +1369,15 @@ DROP TABLE t1;
 SELECT '1' IN ('1', SUBSTRING(-9223372036854775809, 1));
 SELECT CONVERT(('' IN (REVERSE(CAST(('') AS DECIMAL)), '')), CHAR(3));
 
+--echo # 
+--echo # Bug#58165: "my_empty_string" gets modified and causes LOAD DATA to fail
+--echo # and other crashes
+--echo #
+CREATE TABLE t1 ( a TEXT );
+SELECT 'aaaaaaaaaaaaaa' INTO OUTFILE 'bug58165.txt';
+SELECT insert( substring_index( 'a', 'a', 'b' ), 1, 0, 'x' );
+LOAD DATA INFILE 'bug58165.txt' INTO TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
 --echo End of 5.1 tests

=== modified file 'mysql-test/t/gis.test'
--- a/mysql-test/t/gis.test	2010-09-07 11:34:18 +0000
+++ b/mysql-test/t/gis.test	2011-01-14 20:56:09 +0000
@@ -358,7 +358,7 @@ t1 where object_id=85998;
 
 # Expected result is 36.3310176346905, but IA64 returns 36.3310176346904
 # due to fused multiply-add instructions.
---replace_result 36.3310176346904 36.3310176346905
+--replace_result 36.3310176346904 36.3310176346905 -114.87787186923326 -114.87787186923313 36.33101763469053 36.33101763469059 36.33101763469043 36.33101763469059
 select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from
 t1 where object_id=85984;
 
@@ -744,4 +744,14 @@ SET @a=0x0000000003000000000000000000000
 SET @a=POLYFROMWKB(@a);
 
 
+#
+# Bug #57321    crashes and valgrind errors from spatial types
+#
+
+create table t1(a polygon NOT NULL)engine=myisam;
+insert into t1 values (geomfromtext("point(0 1)"));
+insert into t1 values (geomfromtext("point(1 0)"));
+select * from (select polygon(t1.a) as p from t1 order by t1.a) d;
+drop table t1;
+
 --echo End of 5.1 tests

=== modified file 'mysql-test/t/mysqladmin.test'
--- a/mysql-test/t/mysqladmin.test	2007-08-07 09:42:14 +0000
+++ b/mysql-test/t/mysqladmin.test	2011-01-15 20:34:08 +0000
@@ -33,3 +33,15 @@ EOF
 --exec $MYSQLADMIN --defaults-file=$MYSQLTEST_VARDIR/tmp/bug10608.cnf -S $MASTER_MYSOCK -P $MASTER_MYPORT  -u root --password= ping 2>&1
 
 remove_file $MYSQLTEST_VARDIR/tmp/bug10608.cnf;
+
+--echo #
+--echo # Bug#58221 : mysqladmin --sleep=x --count=x keeps looping
+--echo #
+
+--echo # Executing mysqladmin with --sleep=1 and --count=2.
+--exec $MYSQLADMIN -u root -S $MASTER_MYSOCK -P $MASTER_MYPORT --sleep=1 --count=2 ping > $MYSQLTEST_VARDIR/tmp/mysqladmin.tmp
+--echo # Done.
+--echo # Displaying the output :
+--cat_file $MYSQLTEST_VARDIR/tmp/mysqladmin.tmp
+
+--remove_file $MYSQLTEST_VARDIR/tmp/mysqladmin.tmp

=== modified file 'mysql-test/t/mysqlbinlog_row_big.test'
--- a/mysql-test/t/mysqlbinlog_row_big.test	2009-04-02 22:34:18 +0000
+++ b/mysql-test/t/mysqlbinlog_row_big.test	2011-01-12 19:32:45 +0000
@@ -79,8 +79,8 @@ eval CREATE TABLE t1 (
 --echo # Insert some big rows.
 --echo #
 
---echo 256MB
-INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 16777216));
+--echo 64MB
+INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 4194304));
 
 --echo 32MB
 INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 2097152));

=== modified file 'mysql-test/t/mysqldump.test'
--- a/mysql-test/t/mysqldump.test	2010-05-20 15:38:01 +0000
+++ b/mysql-test/t/mysqldump.test	2011-01-14 14:20:34 +0000
@@ -2164,6 +2164,15 @@ SELECT LENGTH(a) FROM t2;
 DROP TABLE t1, t2;
 
 ###########################################################################
+
+--echo #
+--echo # Bug #13618 : mysqldump --xml ommit comment on table field
+--echo #
+
+CREATE TABLE `comment_table` (i INT COMMENT 'FIELD COMMENT') COMMENT = 'TABLE COMMENT';
+--exec $MYSQL_DUMP --compact --skip-create --xml test
+DROP TABLE `comment_table`;
+
 --echo #
 --echo # End of 5.1 tests
 --echo #

=== modified file 'sql/item_geofunc.h'
--- a/sql/item_geofunc.h	2010-09-09 09:40:17 +0000
+++ b/sql/item_geofunc.h	2011-01-12 13:02:41 +0000
@@ -177,6 +177,7 @@ public:
   String *val_str(String *);
   void fix_length_and_dec()
   {
+    Item_geometry_func::fix_length_and_dec();
     for (unsigned int i= 0; i < arg_count; ++i)
     {
       if (args[i]->fixed && args[i]->field_type() != MYSQL_TYPE_GEOMETRY)

=== modified file 'sql/item_strfunc.cc'
--- a/sql/item_strfunc.cc	2010-11-11 10:25:23 +0000
+++ b/sql/item_strfunc.cc	2011-01-13 07:57:15 +0000
@@ -39,6 +39,9 @@ C_MODE_START
 #include "../mysys/my_static.h"			// For soundex_map
 C_MODE_END
 
+/**
+   @todo Remove this. It is not safe to use a shared String object.
+ */
 String my_empty_string("",default_charset_info);
 
 
@@ -461,7 +464,7 @@ String *Item_func_des_encrypt::val_str(S
   if ((null_value= args[0]->null_value))
     return 0;                                   // ENCRYPT(NULL) == NULL
   if ((res_length=res->length()) == 0)
-    return &my_empty_string;
+    return make_empty_result();
 
   if (arg_count == 1)
   {
@@ -652,7 +655,7 @@ String *Item_func_concat_ws::val_str(Str
     }
 
   if (i ==  arg_count)
-    return &my_empty_string;
+    return make_empty_result();
 
   for (i++; i < arg_count ; i++)
   {
@@ -803,7 +806,7 @@ String *Item_func_reverse::val_str(Strin
     return 0;
   /* An empty string is a special case as the string pointer may be null */
   if (!res->length())
-    return &my_empty_string;
+    return make_empty_result();
   if (tmp_value.alloced_length() < res->length() &&
       tmp_value.realloc(res->length()))
   {
@@ -1143,8 +1146,7 @@ String *Item_func_left::val_str(String *
 
   /* if "unsigned_flag" is set, we have a *huge* positive number. */
   if ((length <= 0) && (!args[1]->unsigned_flag))
-    return &my_empty_string;
-
+    return make_empty_result();
   if ((res->length() <= (ulonglong) length) ||
       (res->length() <= (char_pos= res->charpos((int) length))))
     return res;
@@ -1187,7 +1189,7 @@ String *Item_func_right::val_str(String
 
   /* if "unsigned_flag" is set, we have a *huge* positive number. */
   if ((length <= 0) && (!args[1]->unsigned_flag))
-    return &my_empty_string; /* purecov: inspected */
+    return make_empty_result(); /* purecov: inspected */
 
   if (res->length() <= (ulonglong) length)
     return res; /* purecov: inspected */
@@ -1226,7 +1228,7 @@ String *Item_func_substr::val_str(String
   /* Negative or zero length, will return empty string. */
   if ((arg_count == 3) && (length <= 0) && 
       (length == 0 || !args[2]->unsigned_flag))
-    return &my_empty_string;
+    return make_empty_result();
 
   /* Assumes that the maximum length of a String is < INT_MAX32. */
   /* Set here so that rest of code sees out-of-bound value as such. */
@@ -1237,12 +1239,12 @@ String *Item_func_substr::val_str(String
   /* Assumes that the maximum length of a String is < INT_MAX32. */
   if ((!args[1]->unsigned_flag && (start < INT_MIN32 || start > INT_MAX32)) ||
       (args[1]->unsigned_flag && ((ulonglong) start > INT_MAX32)))
-    return &my_empty_string;
+    return make_empty_result();
 
   start= ((start < 0) ? res->numchars() + start : start - 1);
   start= res->charpos((int) start);
   if ((start < 0) || ((uint) start + 1 > res->length()))
-    return &my_empty_string;
+    return make_empty_result();
 
   length= res->charpos((int) length, (uint32) start);
   tmp_length= res->length() - start;
@@ -1305,7 +1307,7 @@ String *Item_func_substr_index::val_str(
   null_value=0;
   uint delimiter_length= delimiter->length();
   if (!res->length() || !delimiter_length || !count)
-    return &my_empty_string;		// Wrong parameters
+    return make_empty_result();		// Wrong parameters
 
   res->set_charset(collation.collation);
 
@@ -1654,7 +1656,7 @@ String *Item_func_password::val_str(Stri
   if ((null_value=args[0]->null_value))
     return 0;
   if (res->length() == 0)
-    return &my_empty_string;
+    return make_empty_result();
   my_make_scrambled_password(tmp_value, res->ptr(), res->length());
   str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, res->charset());
   return str;
@@ -1678,7 +1680,7 @@ String *Item_func_old_password::val_str(
   if ((null_value=args[0]->null_value))
     return 0;
   if (res->length() == 0)
-    return &my_empty_string;
+    return make_empty_result();
   my_make_scrambled_password_323(tmp_value, res->ptr(), res->length());
   str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH_323, res->charset());
   return str;
@@ -1706,8 +1708,7 @@ String *Item_func_encrypt::val_str(Strin
   if ((null_value=args[0]->null_value))
     return 0;
   if (res->length() == 0)
-    return &my_empty_string;
-
+    return make_empty_result();
   if (arg_count == 1)
   {					// generate random salt
     time_t timestamp=current_thd->query_start();
@@ -1967,7 +1968,7 @@ String *Item_func_soundex::val_str(Strin
   for ( ; ; ) /* Skip pre-space */
   {
     if ((rc= cs->cset->mb_wc(cs, &wc, (uchar*) from, (uchar*) end)) <= 0)
-      return &my_empty_string; /* EOL or invalid byte sequence */
+      return make_empty_result(); /* EOL or invalid byte sequence */
     
     if (rc == 1 && cs->ctype)
     {
@@ -1992,7 +1993,7 @@ String *Item_func_soundex::val_str(Strin
         {
           /* Extra safety - should not really happen */
           DBUG_ASSERT(false);
-          return &my_empty_string;
+          return make_empty_result();
         }
         to+= rc;
         break;
@@ -2289,7 +2290,7 @@ String *Item_func_make_set::val_str(Stri
 	  else
 	  {
 	    if (tmp_str.copy(*res))		// Don't use 'str'
-	      return &my_empty_string;
+              return make_empty_result();
 	    result= &tmp_str;
 	  }
 	}
@@ -2299,11 +2300,11 @@ String *Item_func_make_set::val_str(Stri
 	  {					// Copy data to tmp_str
 	    if (tmp_str.alloc(result->length()+res->length()+1) ||
 		tmp_str.copy(*result))
-	      return &my_empty_string;
+              return make_empty_result();
 	    result= &tmp_str;
 	  }
 	  if (tmp_str.append(STRING_WITH_LEN(","), &my_charset_bin) || tmp_str.append(*res))
-	    return &my_empty_string;
+            return make_empty_result();
 	}
       }
     }
@@ -2442,7 +2443,7 @@ String *Item_func_repeat::val_str(String
   null_value= 0;
 
   if (count <= 0 && (count == 0 || !args[1]->unsigned_flag))
-    return &my_empty_string;
+    return make_empty_result();
 
   /* Assumes that the maximum length of a String is < INT_MAX32. */
   /* Bounds check on count:  If this is triggered, we will error. */
@@ -2750,7 +2751,7 @@ String *Item_func_conv::val_str(String *
 
   ptr= longlong2str(dec, ans, to_base);
   if (str->copy(ans, (uint32) (ptr-ans), default_charset()))
-    return &my_empty_string;
+    return make_empty_result();
   return str;
 }
 
@@ -2917,7 +2918,7 @@ String *Item_func_hex::val_str(String *s
       return 0;
     ptr= longlong2str(dec,ans,16);
     if (str->copy(ans,(uint32) (ptr-ans),default_charset()))
-      return &my_empty_string;			// End of memory
+      return make_empty_result();			// End of memory
     return str;
   }
 

=== modified file 'sql/item_strfunc.h'
--- a/sql/item_strfunc.h	2010-03-29 13:42:49 +0000
+++ b/sql/item_strfunc.h	2011-01-13 07:57:15 +0000
@@ -22,6 +22,16 @@
 
 class Item_str_func :public Item_func
 {
+protected:
+  /**
+     Sets the result value of the function an empty string, using the current
+     character set. No memory is allocated.
+     @retval A pointer to the str_value member.
+   */
+  String *make_empty_result() {
+    str_value.set("", 0, collation.collation);
+    return &str_value; 
+  }
 public:
   Item_str_func() :Item_func() { decimals=NOT_FIXED_DEC; }
   Item_str_func(Item *a) :Item_func(a) {decimals=NOT_FIXED_DEC; }

=== modified file 'sql/sql_string.cc'
--- a/sql/sql_string.cc	2010-07-09 12:00:17 +0000
+++ b/sql/sql_string.cc	2011-01-13 07:57:15 +0000
@@ -58,11 +58,33 @@ bool String::real_alloc(uint32 arg_lengt
 }
 
 
-/*
-** Check that string is big enough. Set string[alloc_length] to 0
-** (for C functions)
-*/
+/**
+   Allocates a new buffer on the heap for this String.
+
+   - If the String's internal buffer is privately owned and heap allocated,
+     one of the following is performed.
+
+     - If the requested length is greater than what fits in the buffer, a new
+       buffer is allocated, data moved and the old buffer freed.
+
+     - If the requested length is less or equal to what fits in the buffer, a
+       null character is inserted at the appropriate position.
+
+   - If the String does not keep a private buffer on the heap, such a buffer
+     will be allocated and the string copied accoring to its length, as found
+     in String::length().
+ 
+   For C compatibility, the new string buffer is null terminated.
 
+   @param alloc_length The requested string size in characters, excluding any
+   null terminator.
+
+   @retval false Either the copy operation is complete or, if the size of the
+   new buffer is smaller than the currently allocated buffer (if one exists),
+   no allocation occured.
+
+   @retval true An error occured when attempting to allocate memory.
+*/
 bool String::realloc(uint32 alloc_length)
 {
   uint32 len=ALIGN_SIZE(alloc_length+1);
@@ -196,6 +218,17 @@ bool String::copy()
   return FALSE;
 }
 
+/**
+   Copies the internal buffer from str. If this String has a private heap
+   allocated buffer where new data does not fit, a new buffer is allocated
+   before copying and the old buffer freed. Character set information is also
+   copied.
+   
+   @param str The string whose internal buffer is to be copied.
+   
+   @retval false Success.
+   @retval true Memory allocation failed.
+*/
 bool String::copy(const String &str)
 {
   if (alloc(str.str_length))

=== modified file 'sql/sql_string.h'
--- a/sql/sql_string.h	2010-10-19 22:36:59 +0000
+++ b/sql/sql_string.h	2011-01-13 07:57:15 +0000
@@ -136,6 +136,16 @@ public:
       Alloced_length=0;
     str_charset=str.str_charset;
   }
+
+
+  /**
+     Points the internal buffer to the supplied one. The old buffer is freed.
+     @param str Pointer to the new buffer.
+     @param arg_length Length of the new buffer in characters, excluding any 
+            null character.
+     @param cs Character set to use for interpreting string data.
+     @note The new buffer will not be null terminated.
+  */
   inline void set(char *str,uint32 arg_length, CHARSET_INFO *cs)
   {
     free();

No bundle (reason: revision is a merge).
Thread
bzr commit into mysql-5.1-mtr branch (bjorn.munch:2969) Bjorn Munch17 Jan