diff options
author | Bjorn Munch <bjorn.munch@oracle.com> | 2011-01-17 10:28:53 +0100 |
---|---|---|
committer | Bjorn Munch <bjorn.munch@oracle.com> | 2011-01-17 10:28:53 +0100 |
commit | 8ed50d99721130f1431d1b41491f4ad8232beeed (patch) | |
tree | 2148d39a13e0342996f9ccdf5f7c6ccb8b9f5912 | |
parent | 251869175e157a21d35191b301ef597a0aad986b (diff) | |
parent | 208b677637ef9d140c1629a0de4d4963c02ea533 (diff) | |
download | mariadb-git-8ed50d99721130f1431d1b41491f4ad8232beeed.tar.gz |
merge from 5.1 main
-rw-r--r-- | client/mysqladmin.cc | 3 | ||||
-rw-r--r-- | client/mysqldump.c | 13 | ||||
-rw-r--r-- | client/mysqlslap.c | 20 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | mysql-test/include/rpl_start_server.inc | 10 | ||||
-rw-r--r-- | mysql-test/include/rpl_stop_server.inc | 4 | ||||
-rw-r--r-- | mysql-test/r/client_xml.result | 6 | ||||
-rw-r--r-- | mysql-test/r/func_str.result | 16 | ||||
-rw-r--r-- | mysql-test/r/gis.result | 8 | ||||
-rw-r--r-- | mysql-test/r/mysqladmin.result | 8 | ||||
-rw-r--r-- | mysql-test/r/mysqlbinlog_row_big.result | 8 | ||||
-rw-r--r-- | mysql-test/r/mysqldump.result | 37 | ||||
-rw-r--r-- | mysql-test/t/func_str.test | 11 | ||||
-rw-r--r-- | mysql-test/t/gis.test | 12 | ||||
-rw-r--r-- | mysql-test/t/mysqladmin.test | 12 | ||||
-rw-r--r-- | mysql-test/t/mysqlbinlog_row_big.test | 4 | ||||
-rw-r--r-- | mysql-test/t/mysqldump.test | 9 | ||||
-rw-r--r-- | sql/item_geofunc.h | 1 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 45 | ||||
-rw-r--r-- | sql/item_strfunc.h | 10 | ||||
-rw-r--r-- | sql/sql_string.cc | 41 | ||||
-rw-r--r-- | sql/sql_string.h | 10 |
22 files changed, 233 insertions, 57 deletions
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index fe3e51a4d61..18ee8fae400 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -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 diff --git a/client/mysqldump.c b/client/mysqldump.c index e35672c2a2c..57e3f5b0349 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -2247,6 +2247,15 @@ static uint get_table_structure(char *table, char *db, char *table_type, 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 *table, char *db, char *table_type, 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); diff --git a/client/mysqlslap.c b/client/mysqlslap.c index b1eafe0082c..3b5c14dd74b 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -1519,7 +1519,12 @@ generate_primary_key_list(MYSQL *mysql, option_string *engine_stmt) 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++; diff --git a/configure.in b/configure.in index 7a35e8587d4..3849c362eec 100644 --- a/configure.in +++ b/configure.in @@ -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 diff --git a/mysql-test/include/rpl_start_server.inc b/mysql-test/include/rpl_start_server.inc index c59c7759910..ac8106f141c 100644 --- a/mysql-test/include/rpl_start_server.inc +++ b/mysql-test/include/rpl_start_server.inc @@ -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 diff --git a/mysql-test/include/rpl_stop_server.inc b/mysql-test/include/rpl_stop_server.inc index e1f8839dd69..a90981d6de8 100644 --- a/mysql-test/include/rpl_stop_server.inc +++ b/mysql-test/include/rpl_stop_server.inc @@ -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 diff --git a/mysql-test/r/client_xml.result b/mysql-test/r/client_xml.result index aa4bdb2bd61..7f74a092af7 100644 --- a/mysql-test/r/client_xml.result +++ b/mysql-test/r/client_xml.result @@ -21,9 +21,9 @@ insert into t1 values (1, 2, 'a&b a<b a>b'); <mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <database name="test"> <table_structure name="t1"> - <field Field="a&b" Type="int(11)" Null="YES" Key="" Extra="" /> - <field Field="a<b" Type="int(11)" Null="YES" Key="" Extra="" /> - <field Field="a>b" Type="text" Null="YES" Key="" Extra="" /> + <field Field="a&b" Type="int(11)" Null="YES" Key="" Extra="" Comment="" /> + <field Field="a<b" Type="int(11)" Null="YES" Key="" Extra="" Comment="" /> + <field Field="a>b" Type="text" Null="YES" Key="" Extra="" Comment="" /> </table_structure> <table_data name="t1"> <row> diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 0321b2d85ad..8f4038e1239 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -2612,4 +2612,20 @@ CONVERT(('' IN (REVERSE(CAST(('') AS DECIMAL)), '')), CHAR(3)) 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 diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 3b18ee61336..f4aa361ffcf 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -1014,4 +1014,12 @@ SET @a=0x00000000030000000100000000000000000000000000144000000000000014400000000 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 diff --git a/mysql-test/r/mysqladmin.result b/mysql-test/r/mysqladmin.result index 57927f8aa67..748152bffcc 100644 --- a/mysql-test/r/mysqladmin.result +++ b/mysql-test/r/mysqladmin.result @@ -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 diff --git a/mysql-test/r/mysqlbinlog_row_big.result b/mysql-test/r/mysqlbinlog_row_big.result index 46fa0dc79cd..0bdbfdcee3a 100644 --- a/mysql-test/r/mysqlbinlog_row_big.result +++ b/mysql-test/r/mysqlbinlog_row_big.result @@ -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 Warnings: 0 # 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 diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index d26eaac7a93..289e7f66406 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -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"), (2, "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"b"" Type="char(2)" Null="YES" Key="" Extra="" /> + <field Field="a"b"" 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 # diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index fdcfbcf519e..92c4bae5327 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -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 diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index fd0a18ab4dd..bdbbfc7c064 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -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=0x00000000030000000000000000000000000000000000144000000000000014400000000 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 diff --git a/mysql-test/t/mysqladmin.test b/mysql-test/t/mysqladmin.test index 839ecf00b60..a2b12dbc9b6 100644 --- a/mysql-test/t/mysqladmin.test +++ b/mysql-test/t/mysqladmin.test @@ -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 diff --git a/mysql-test/t/mysqlbinlog_row_big.test b/mysql-test/t/mysqlbinlog_row_big.test index 75f3b90269f..ffd1b79af34 100644 --- a/mysql-test/t/mysqlbinlog_row_big.test +++ b/mysql-test/t/mysqlbinlog_row_big.test @@ -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)); diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 9246d488dd8..fe0b05dbb42 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -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 # diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index b3ecbc39933..08161badfd3 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -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) diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index fd5c47d25cb..204a2dfc663 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -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(String *str) 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(String *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(String *str) 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 *str) /* 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 *str) /* 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 *str) /* 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 *str) /* 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(String *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(String *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(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(String *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(String *str) 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(String *str) 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(String *str) { /* 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(String *str) 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(String *str) { // 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 *str) 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 *str) 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 *str) 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; } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index ab2bf006032..6645a4c637a 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -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; } diff --git a/sql/sql_string.cc b/sql/sql_string.cc index a41f4d52101..4f76943bde7 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -58,11 +58,33 @@ bool String::real_alloc(uint32 arg_length) } -/* -** 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)) diff --git a/sql/sql_string.h b/sql/sql_string.h index b15179bcbe5..092e194646f 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -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(); |