← Back to team overview

maria-developers team mailing list archive

bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (knielsen:2775)

 

#At lp:maria

 2775 knielsen@xxxxxxxxxxxxxxx	2009-12-16 [merge]
      Automatic merge of PBXT rc3 into MariaDB trunk.
      modified:
        client/mysql.cc
        client/mysqlcheck.c
        client/mysqlslap.c
        client/mysqltest.cc
        cmd-line-utils/readline/config_readline.h
        mysql-test/lib/mtr_report.pm
        mysql-test/mysql-test-run.pl
        mysql-test/r/ctype_ucs.result
        mysql-test/suite/federated/disabled.def
        mysql-test/suite/federated/federated_server.result
        mysql-test/suite/federated/federated_server.test
        mysql-test/t/ctype_ucs.test
        sql-common/client.c
        sql/mysqld.cc
        sql/share/errmsg.txt
        sql/sql_base.cc
        sql/sql_class.cc
        sql/sql_insert.cc
        storage/federatedx/ha_federatedx.cc
        strings/ctype-uca.c
        strings/ctype-ucs2.c
        unittest/mysys/Makefile.am

=== modified file 'client/mysql.cc'
--- a/client/mysql.cc	2009-11-30 21:37:27 +0000
+++ b/client/mysql.cc	2009-12-03 11:34:11 +0000
@@ -1280,7 +1280,6 @@ sig_handler handle_sigint(int sig)
   MYSQL *kill_mysql= NULL;
 
   /* terminate if no query being executed, or we already tried interrupting */
-  /* terminate if no query being executed, or we already tried interrupting */
   if (!executing_query || (interrupted_query == 2))
   {
     tee_fprintf(stdout, "Ctrl-C -- exit!\n");
@@ -1295,6 +1294,7 @@ sig_handler handle_sigint(int sig)
     goto err;
   }
 
+  /* First time try to kill the query, second time the connection */
   interrupted_query++;
 
   /* mysqld < 5 does not understand KILL QUERY, skip to KILL CONNECTION */
@@ -1305,10 +1305,13 @@ sig_handler handle_sigint(int sig)
   sprintf(kill_buffer, "KILL %s%lu",
           (interrupted_query == 1) ? "QUERY " : "",
           mysql_thread_id(&mysql));
-  tee_fprintf(stdout, "Ctrl-C -- sending \"%s\" to server ...\n", kill_buffer);
+  if (verbose)
+    tee_fprintf(stdout, "Ctrl-C -- sending \"%s\" to server ...\n",
+                kill_buffer);
   mysql_real_query(kill_mysql, kill_buffer, (uint) strlen(kill_buffer));
   mysql_close(kill_mysql);
-  tee_fprintf(stdout, "Ctrl-C -- query aborted.\n");
+  tee_fprintf(stdout, "Ctrl-C -- query killed. Continuing normally.\n");
+  interrupted_query= 0;
 
   return;
 
@@ -1321,7 +1324,6 @@ err:
    handler called mysql_end(). 
   */
   mysql_thread_end();
-  return;
 #else
   mysql_end(sig);
 #endif  
@@ -2881,13 +2883,8 @@ com_help(String *buffer __attribute__((u
 	  return com_server_help(buffer,line,help_arg);
   }
 
-  put_info("\nFor information about MySQL products and services, visit:\n"
-           "   http://www.mysql.com/\n";
-           "For developer information, including the MySQL Reference Manual, "
-           "visit:\n"
-           "   http://dev.mysql.com/\n";
-           "To buy MySQL Enterprise support, training, or other products, visit:\n"
-           "   https://shop.mysql.com/\n";, INFO_INFO);
+  put_info("\nGeneral information about MariaDB can be found at\n"
+           "http://askmonty.org/wiki/index.php/Manual:Contents\n";, INFO_INFO);
   put_info("List of all MySQL commands:", INFO_INFO);
   if (!named_cmds)
     put_info("Note that all text commands must be first on line and end with ';'",INFO_INFO);

=== modified file 'client/mysqlcheck.c'
--- a/client/mysqlcheck.c	2009-09-28 06:24:19 +0000
+++ b/client/mysqlcheck.c	2009-12-03 11:19:05 +0000
@@ -857,7 +857,8 @@ int main(int argc, char **argv)
 
   if (!opt_write_binlog)
   {
-    if (disable_binlog()) {
+    if (disable_binlog())
+    {
       first_error= 1;
       goto end;
     }

=== modified file 'client/mysqlslap.c'
--- a/client/mysqlslap.c	2009-11-30 21:37:27 +0000
+++ b/client/mysqlslap.c	2009-12-03 11:34:11 +0000
@@ -472,11 +472,10 @@ void concurrency_loop(MYSQL *mysql, uint
     if (commit_rate)
       run_query(mysql, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
 
-    if (pre_system)
-      if ((sysret= system(pre_system)) != 0)
-        fprintf(stderr,
-                "Warning: Execution of pre_system option returned %d.\n", 
-                sysret);
+    if (pre_system && (sysret= system(pre_system)) != 0)
+      fprintf(stderr,
+              "Warning: Execution of pre_system option returned %d.\n", 
+              sysret);
 
     /* 
       Pre statements are always run after all other logic so they can 
@@ -490,11 +489,10 @@ void concurrency_loop(MYSQL *mysql, uint
     if (post_statements)
       run_statements(mysql, post_statements);
 
-    if (post_system)
-      if ((sysret= system(post_system)) != 0)
-        fprintf(stderr,
-                "Warning: Execution of post_system option returned %d.\n", 
-                sysret);
+    if (post_system && (sysret= system(post_system)) != 0)
+      fprintf(stderr,
+              "Warning: Execution of post_system option returned %d.\n", 
+              sysret);
     /* We are finished with this run */
     if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
       drop_primary_key_list();

=== modified file 'client/mysqltest.cc'
--- a/client/mysqltest.cc	2009-11-16 20:49:51 +0000
+++ b/client/mysqltest.cc	2009-12-03 11:19:05 +0000
@@ -3497,9 +3497,10 @@ void do_diff_files(struct st_command *co
   if ((error= compare_files(ds_filename.str, ds_filename2.str)) &&
       match_expected_error(command, error, NULL) < 0)
   {
-    /* Compare of the two files failed, append them to output
-       so the failure can be analyzed, but only if it was not
-       expected to fail.
+    /*
+      Compare of the two files failed, append them to output
+      so the failure can be analyzed, but only if it was not
+      expected to fail.
     */
     show_diff(&ds_res, ds_filename.str, ds_filename2.str);
     log_file.write(&ds_res);
@@ -5013,7 +5014,8 @@ void do_connect(struct st_command *comma
   con_options= ds_options.str;
   while (*con_options)
   {
-    char* end;
+    size_t length;
+    char *end;
     /* Step past any spaces in beginning of option*/
     while (*con_options && my_isspace(charset_info, *con_options))
      con_options++;
@@ -5021,13 +5023,14 @@ void do_connect(struct st_command *comma
     end= con_options;
     while (*end && !my_isspace(charset_info, *end))
       end++;
-    if (!strncmp(con_options, "SSL", 3))
+    length= (size_t) (end - con_options);
+    if (length == 3 && !strncmp(con_options, "SSL", 3))
       con_ssl= 1;
-    else if (!strncmp(con_options, "COMPRESS", 8))
+    else if (length == 8 && !strncmp(con_options, "COMPRESS", 8))
       con_compress= 1;
-    else if (!strncmp(con_options, "PIPE", 4))
+    else if (length == 4 && !strncmp(con_options, "PIPE", 4))
       con_pipe= 1;
-    else if (!strncmp(con_options, "SHM", 3))
+    else if (length == 3 && !strncmp(con_options, "SHM", 3))
       con_shm= 1;
     else
       die("Illegal option to connect: %.*s", 
@@ -5096,14 +5099,13 @@ void do_connect(struct st_command *comma
     mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, ds_shm.str);
     mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol);
   }
-  else if(shared_memory_base_name)
+  else if (shared_memory_base_name)
   {
     mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME,
-      shared_memory_base_name);
+                  shared_memory_base_name);
   }
 #endif
 
-
   /* Use default db name */
   if (ds_database.length == 0)
     dynstr_set(&ds_database, opt_db);
@@ -6879,10 +6881,8 @@ void run_query_stmt(MYSQL *mysql, struct
   MYSQL_STMT *stmt;
   DYNAMIC_STRING ds_prepare_warnings;
   DYNAMIC_STRING ds_execute_warnings;
-  ulonglong affected_rows;
   DBUG_ENTER("run_query_stmt");
   DBUG_PRINT("query", ("'%-.60s'", query));
-  LINT_INIT(affected_rows);
 
   /*
     Init a new stmt if it's not already one created for this connection
@@ -6981,6 +6981,9 @@ void run_query_stmt(MYSQL *mysql, struct
   handle_no_error(command);
   if (!disable_result_log)
   {
+    ulonglong affected_rows;
+    LINT_INIT(affected_rows);
+
     /*
       Not all statements creates a result set. If there is one we can
       now create another normal result set that contains the meta
@@ -7026,39 +7029,33 @@ void run_query_stmt(MYSQL *mysql, struct
       Need to grab affected rows information before getting
       warnings here
     */
-    {
-      ulonglong affected_rows;
-      LINT_INIT(affected_rows);
+    if (!disable_info)
+      affected_rows= mysql_affected_rows(mysql);
 
-      if (!disable_info)
-	affected_rows= mysql_affected_rows(mysql);
+    if (!disable_warnings)
+    {
+      /* Get the warnings from execute */
 
-      if (!disable_warnings)
+      /* Append warnings to ds - if there are any */
+      if (append_warnings(&ds_execute_warnings, mysql) ||
+          ds_execute_warnings.length ||
+          ds_prepare_warnings.length ||
+          ds_warnings->length)
       {
-	/* Get the warnings from execute */
-
-	/* Append warnings to ds - if there are any */
-	if (append_warnings(&ds_execute_warnings, mysql) ||
-	    ds_execute_warnings.length ||
-	    ds_prepare_warnings.length ||
-	    ds_warnings->length)
-	{
-	  dynstr_append_mem(ds, "Warnings:\n", 10);
-	  if (ds_warnings->length)
-	    dynstr_append_mem(ds, ds_warnings->str,
-			      ds_warnings->length);
-	  if (ds_prepare_warnings.length)
-	    dynstr_append_mem(ds, ds_prepare_warnings.str,
-			      ds_prepare_warnings.length);
-	  if (ds_execute_warnings.length)
-	    dynstr_append_mem(ds, ds_execute_warnings.str,
-			      ds_execute_warnings.length);
-	}
+        dynstr_append_mem(ds, "Warnings:\n", 10);
+        if (ds_warnings->length)
+          dynstr_append_mem(ds, ds_warnings->str,
+                            ds_warnings->length);
+        if (ds_prepare_warnings.length)
+          dynstr_append_mem(ds, ds_prepare_warnings.str,
+                            ds_prepare_warnings.length);
+        if (ds_execute_warnings.length)
+          dynstr_append_mem(ds, ds_execute_warnings.str,
+                            ds_execute_warnings.length);
       }
-
-      if (!disable_info)
-	append_info(ds, affected_rows, mysql_info(mysql));
     }
+    if (!disable_info)
+      append_info(ds, affected_rows, mysql_info(mysql));
   }
 
 end:
@@ -7235,7 +7232,6 @@ void run_query(struct st_connection *cn,
     }
 
     dynstr_free(&query_str);
-
   }
 
   if (sp_protocol_enabled &&
@@ -7662,6 +7658,7 @@ int main(int argc, char **argv)
   my_bool q_send_flag= 0, abort_flag= 0;
   uint command_executed= 0, last_command_executed= 0;
   char save_file[FN_REFLEN];
+  bool empty_result= FALSE;
   MY_INIT(argv[0]);
 
   save_file[0]= 0;
@@ -7819,6 +7816,7 @@ int main(int argc, char **argv)
   verbose_msg("Start processing test commands from '%s' ...", cur_file->file_name);
   while (!read_command(&command) && !abort_flag)
   {
+    my_bool ok_to_do;
     int current_line_inc = 1, processed = 0;
     if (command->type == Q_UNKNOWN || command->type == Q_COMMENT_WITH_COMMAND)
       get_command_type(command);
@@ -7831,7 +7829,7 @@ int main(int argc, char **argv)
       command->type= Q_COMMENT;
     }
 
-    my_bool ok_to_do= cur_block->ok;
+    ok_to_do= cur_block->ok;
     /*
       Some commands need to be "done" the first time if they may get
       re-iterated over in a true context. This can only happen if there's 
@@ -8167,8 +8165,6 @@ int main(int argc, char **argv)
   if (parsing_disabled)
     die("Test ended with parsing disabled");
 
-  my_bool empty_result= FALSE;
-  
   /*
     The whole test has been executed _sucessfully_.
     Time to compare result or save it to record file.

=== modified file 'cmd-line-utils/readline/config_readline.h'
--- a/cmd-line-utils/readline/config_readline.h	2009-11-30 21:37:27 +0000
+++ b/cmd-line-utils/readline/config_readline.h	2009-12-01 16:09:02 +0000
@@ -7,6 +7,13 @@
 #  include <config.h>
 #endif
 
+#ifdef NOT_YET /* causes problem on MacOSX */
+/* to get wcwidth() defined */
+#define _XOPEN_SOURCE 600
+#define _XOPEN_SOURCE_EXTENDED
+#define _XOPEN_
+#endif
+
 /*
  Ultrix botches type-ahead when switching from canonical to
    non-canonical mode, at least through version 4.3

=== modified file 'mysql-test/lib/mtr_report.pm'
--- a/mysql-test/lib/mtr_report.pm	2009-11-16 20:49:51 +0000
+++ b/mysql-test/lib/mtr_report.pm	2009-12-03 11:19:05 +0000
@@ -388,7 +388,7 @@ MSG
   }
   elsif (@$extra_warnings)
   {
-    mtr_error("There were errors/warnings in server logs after running test cases.");
+    mtr_error("There where errors/warnings in server logs after running test cases.");
   }
   elsif ($fail)
   {

=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl	2009-11-30 21:37:27 +0000
+++ b/mysql-test/mysql-test-run.pl	2009-12-03 11:34:11 +0000
@@ -201,10 +201,10 @@ my $opt_mark_progress;
 
 my $opt_sleep;
 
-my $opt_testcase_timeout=    15; # minutes
-my $opt_suite_timeout   =   300; # minutes
-my $opt_shutdown_timeout=    10; # seconds
-my $opt_start_timeout   =   180; # seconds
+my $opt_testcase_timeout=     15; # 15 minutes
+my $opt_suite_timeout   =    360; # 6 hours
+my $opt_shutdown_timeout=     10; # 10 seconds
+my $opt_start_timeout   =    180; # 180 seconds
 
 sub testcase_timeout { return $opt_testcase_timeout * 60; };
 sub suite_timeout { return $opt_suite_timeout * 60; };
@@ -1319,6 +1319,8 @@ sub command_line_setup {
   {
     # Indicate that we are using debugger
     $glob_debugger= 1;
+    $opt_testcase_timeout= 60*60*24;  # Don't abort debugging with timeout
+    $opt_suite_timeout= $opt_testcase_timeout;
     $opt_retry= 1;
     $opt_retry_failure= 1;
 
@@ -2151,7 +2153,6 @@ sub environment_setup {
   # Create an environment variable to make it possible
   # to detect that valgrind is being used from test cases
   $ENV{'VALGRIND_TEST'}= $opt_valgrind;
-
 }
 
 
@@ -2908,8 +2909,8 @@ sub mysql_install_db {
   my $bootstrap_sql_file= "$opt_vardir/tmp/bootstrap.sql";
 
   my $path_sql= my_find_file($install_basedir,
-			     ["mysql", "sql/share", "share/mysql",
-			      "share/mariadb", "share", "scripts"],
+			     ["mysql", "sql/share", "share/mariadb",
+			      "share/mysql", "share", "scripts"],
 			     "mysql_system_tables.sql",
 			     NOT_REQUIRED);
 
@@ -3861,7 +3862,7 @@ sub extract_server_log ($$) {
   my ($error_log, $tname) = @_;
 
   # Open the servers .err log file and read all lines
-  # belonging to current tets into @lines
+  # belonging to current test into @lines
   my $Ferr = IO::File->new($error_log)
     or mtr_error("Could not open file '$error_log' for reading: $!");
 

=== modified file 'mysql-test/r/ctype_ucs.result'
--- a/mysql-test/r/ctype_ucs.result	2008-12-23 14:21:01 +0000
+++ b/mysql-test/r/ctype_ucs.result	2009-12-03 12:02:37 +0000
@@ -1211,3 +1211,47 @@ HEX(DAYNAME(19700101))
 0427043504420432043504400433
 SET character_set_connection=latin1;
 End of 5.0 tests
+Start of 5.1 tests
+SET NAMES utf8;
+CREATE TABLE t1 (
+a varchar(10) CHARACTER SET ucs2 COLLATE ucs2_czech_ci,
+key(a)
+);
+INSERT INTO t1 VALUES
+('aa'),('bb'),('cc'),('dd'),('ee'),('ff'),('gg'),('hh'),('ii'),
+('jj'),('kk'),('ll'),('mm'),('nn'),('oo'),('pp'),('rr'),('ss'),
+('tt'),('uu'),('vv'),('ww'),('xx'),('yy'),('zz');
+INSERT INTO t1 VALUES ('ca'),('cz'),('ch');
+INSERT INTO t1 VALUES ('da'),('dz'), (X'0064017E');
+EXPLAIN SELECT * FROM t1 WHERE a LIKE 'b%';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	a	a	23	NULL	1	Using where; Using index
+EXPLAIN SELECT * FROM t1 WHERE a LIKE 'c%';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	a	a	23	NULL	30	Using where; Using index
+SELECT * FROM t1 WHERE a LIKE 'c%';
+a
+ca
+cc
+cz
+ch
+EXPLAIN SELECT * FROM t1 WHERE a LIKE 'ch%';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	a	a	23	NULL	1	Using where; Using index
+SELECT * FROM t1 WHERE a LIKE 'ch%';
+a
+ch
+ALTER TABLE t1 MODIFY a VARCHAR(10) CHARACTER SET ucs2 COLLATE ucs2_croatian_ci;
+EXPLAIN SELECT * FROM t1 WHERE a LIKE 'd%';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	a	a	23	NULL	1	Using where; Using index
+SELECT hex(concat('d',_ucs2 0x017E,'%'));
+hex(concat('d',_ucs2 0x017E,'%'))
+0064017E0025
+EXPLAIN SELECT * FROM t1 WHERE a LIKE concat('d',_ucs2 0x017E,'%');
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	a	a	23	NULL	1	Using where; Using index
+SELECT hex(a) FROM t1 WHERE a LIKE concat('D',_ucs2 0x017E,'%');
+hex(a)
+0064017E
+DROP TABLE t1;

=== modified file 'mysql-test/suite/federated/disabled.def'
--- a/mysql-test/suite/federated/disabled.def	2009-10-30 18:50:56 +0000
+++ b/mysql-test/suite/federated/disabled.def	2009-11-14 19:33:59 +0000
@@ -9,5 +9,4 @@
 #  Do not use any TAB characters for whitespace.
 #
 ##############################################################################
-federated_server : needs fixup
 

=== modified file 'mysql-test/suite/federated/federated_server.result'
--- a/mysql-test/suite/federated/federated_server.result	2009-10-30 18:50:56 +0000
+++ b/mysql-test/suite/federated/federated_server.result	2009-11-14 19:33:59 +0000
@@ -175,6 +175,8 @@ CREATE TABLE db_bogus.t1 (
     )
 ;
 INSERT INTO db_bogus.t1 VALUES ('2','this is bogus');
+create user test_fed@localhost identified by 'foo';
+grant all on db_legitimate.* to test_fed@localhost;
 create server 's1' foreign data wrapper 'mysql' options
 (HOST '127.0.0.1',
 DATABASE 'db_legitimate',
@@ -211,15 +213,14 @@ id	name
 alter server s1 options (database 'db_bogus');
 flush tables;
 select * from federated.t1;
-id	name
-2	this is bogus
+ERROR HY000: There was a problem processing the query on the foreign data source. Data source error: : 1044 : Access denied for user 'test_fed'@'localhost' to databa
 drop server if exists 's1';
 ERROR 42000: Access denied; you need the SUPER privilege for this operation
 create server 's1' foreign data wrapper 'mysql' options
 (HOST '127.0.0.1',
 DATABASE 'db_legitimate',
-USER 'root',
-PASSWORD '',
+USER 'test_fed',
+PASSWORD 'foo',
 PORT SLAVE_PORT,
 SOCKET '',
 OWNER 'root');
@@ -228,8 +229,8 @@ drop server 's1';
 create server 's1' foreign data wrapper 'mysql' options
 (HOST '127.0.0.1',
 DATABASE 'db_legitimate',
-USER 'root',
-PASSWORD '',
+USER 'test_fed',
+PASSWORD 'foo',
 PORT SLAVE_PORT,
 SOCKET '',
 OWNER 'root');
@@ -237,6 +238,7 @@ flush tables;
 select * from federated.t1;
 id	name
 1	this is legitimate
+drop user test_fed@localhost;
 drop database db_legitimate;
 drop database db_bogus;
 drop user guest_super@localhost;
@@ -275,6 +277,6 @@ call p1();
 drop procedure p1;
 drop server if exists s;
 DROP TABLE IF EXISTS federated.t1;
-DROP DATABASE federated;
+DROP DATABASE IF EXISTS federated;
 DROP TABLE IF EXISTS federated.t1;
-DROP DATABASE federated;
+DROP DATABASE IF EXISTS federated;

=== modified file 'mysql-test/suite/federated/federated_server.test'
--- a/mysql-test/suite/federated/federated_server.test	2009-10-30 18:50:56 +0000
+++ b/mysql-test/suite/federated/federated_server.test	2009-11-14 19:33:59 +0000
@@ -239,6 +239,7 @@ alter server s1 options (database 'db_bo
 
 connection master;
 flush tables;
+--error ER_QUERY_ON_FOREIGN_DATA_SOURCE
 select * from federated.t1;
 
 connection conn_select;
@@ -249,8 +250,8 @@ drop server if exists 's1';
 eval create server 's1' foreign data wrapper 'mysql' options
   (HOST '127.0.0.1',
   DATABASE 'db_legitimate',
-  USER 'root',
-  PASSWORD '',
+  USER 'test_fed',
+  PASSWORD 'foo',
   PORT $SLAVE_MYPORT,
   SOCKET '',
   OWNER 'root');
@@ -261,8 +262,8 @@ drop server 's1';
 eval create server 's1' foreign data wrapper 'mysql' options
   (HOST '127.0.0.1',
   DATABASE 'db_legitimate',
-  USER 'root',
-  PASSWORD '',
+  USER 'test_fed',
+  PASSWORD 'foo',
   PORT $SLAVE_MYPORT,
   SOCKET '',
   OWNER 'root');
@@ -273,6 +274,7 @@ select * from federated.t1;
 
 # clean up test
 connection slave;
+drop user test_fed@localhost;
 drop database db_legitimate;
 drop database db_bogus;
 

=== modified file 'mysql-test/t/ctype_ucs.test'
--- a/mysql-test/t/ctype_ucs.test	2008-12-23 14:21:01 +0000
+++ b/mysql-test/t/ctype_ucs.test	2009-12-03 12:02:37 +0000
@@ -723,3 +723,34 @@ SELECT HEX(DAYNAME(19700101));
 SET character_set_connection=latin1;
 
 --echo End of 5.0 tests
+
+
+--echo Start of 5.1 tests
+#
+# Checking my_like_range_ucs2
+#
+SET NAMES utf8;
+CREATE TABLE t1 (
+  a varchar(10) CHARACTER SET ucs2 COLLATE ucs2_czech_ci,
+  key(a)
+);
+INSERT INTO t1 VALUES
+('aa'),('bb'),('cc'),('dd'),('ee'),('ff'),('gg'),('hh'),('ii'),
+('jj'),('kk'),('ll'),('mm'),('nn'),('oo'),('pp'),('rr'),('ss'),
+('tt'),('uu'),('vv'),('ww'),('xx'),('yy'),('zz');
+INSERT INTO t1 VALUES ('ca'),('cz'),('ch');
+INSERT INTO t1 VALUES ('da'),('dz'), (X'0064017E');
+# This one should scan only one row
+EXPLAIN SELECT * FROM t1 WHERE a LIKE 'b%';
+# This one should scan many rows: 'c' is a contraction head
+EXPLAIN SELECT * FROM t1 WHERE a LIKE 'c%';
+SELECT * FROM t1 WHERE a LIKE 'c%';
+EXPLAIN SELECT * FROM t1 WHERE a LIKE 'ch%';
+SELECT * FROM t1 WHERE a LIKE 'ch%';
+ALTER TABLE t1 MODIFY a VARCHAR(10) CHARACTER SET ucs2 COLLATE ucs2_croatian_ci;
+EXPLAIN SELECT * FROM t1 WHERE a LIKE 'd%';
+SELECT hex(concat('d',_ucs2 0x017E,'%'));
+EXPLAIN SELECT * FROM t1 WHERE a LIKE concat('d',_ucs2 0x017E,'%');
+SELECT hex(a) FROM t1 WHERE a LIKE concat('D',_ucs2 0x017E,'%');
+
+DROP TABLE t1;

=== modified file 'sql-common/client.c'
--- a/sql-common/client.c	2009-11-16 20:49:51 +0000
+++ b/sql-common/client.c	2009-12-03 15:26:54 +0000
@@ -3208,7 +3208,7 @@ const char * STDCALL mysql_error(MYSQL *
     mysql		Connection
 
   EXAMPLE
-    4.1.0-alfa ->  40100
+    MariaDB-4.1.0-alfa ->  40100
   
   NOTES
     We will ensure that a newer server always has a bigger number.
@@ -3221,7 +3221,11 @@ ulong STDCALL
 mysql_get_server_version(MYSQL *mysql)
 {
   uint major, minor, version;
-  char *pos= mysql->server_version, *end_pos;
+  const char *pos= mysql->server_version;
+  char *end_pos;
+  /* Skip possible prefix */
+  while (*pos && !my_isdigit(&my_charset_latin1, *pos))
+    pos++;
   major=   (uint) strtoul(pos, &end_pos, 10);	pos=end_pos+1;
   minor=   (uint) strtoul(pos, &end_pos, 10);	pos=end_pos+1;
   version= (uint) strtoul(pos, &end_pos, 10);

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2009-11-30 21:37:27 +0000
+++ b/sql/mysqld.cc	2009-12-04 15:12:22 +0000
@@ -4169,8 +4169,10 @@ server.");
         Need to unlock as global_system_variables.table_plugin
         was acquired during plugin_init()
       */
+      pthread_mutex_lock(&LOCK_global_system_variables);
       plugin_unlock(0, global_system_variables.table_plugin);
       global_system_variables.table_plugin= plugin;
+      pthread_mutex_unlock(&LOCK_global_system_variables);
     }
   }
 #if defined(WITH_MARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES)

=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt	2009-11-16 20:49:51 +0000
+++ b/sql/share/errmsg.txt	2009-12-04 15:12:22 +0000
@@ -5322,8 +5322,8 @@ ER_DIVISION_BY_ZERO 22012 
         eng "Division by 0"
         ger "Division durch 0"
 ER_TRUNCATED_WRONG_VALUE_FOR_FIELD  
-        eng "Incorrect %-.32s value: '%-.128s' for column '%.192s' at row %ld"
-        ger "Falscher %-.32s-Wert: '%-.128s' f�d '%.192s' in Zeile %ld"
+        eng "Incorrect %-.32s value: '%-.128s' for column '%.192s' at row %lu"
+        ger "Falscher %-.32s-Wert: '%-.128s' f�d '%.192s' in Zeile %lu"
 ER_ILLEGAL_VALUE_FOR_TYPE 22007 
         eng "Illegal %s '%-.192s' value found during parsing"
         ger "Nicht zul�iger %s-Wert '%-.192s' beim Parsen gefunden"

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2009-11-30 21:37:27 +0000
+++ b/sql/sql_base.cc	2009-12-04 15:12:22 +0000
@@ -8488,19 +8488,26 @@ bool remove_table_from_cache(THD *thd, c
   	  result=1;
         }
         /* Kill delayed insert threads */
-        if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
-            ! in_use->killed)
+        if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT))
         {
-	  in_use->killed= THD::KILL_CONNECTION;
-	  pthread_mutex_lock(&in_use->mysys_var->mutex);
-	  if (in_use->mysys_var->current_cond)
-	  {
-	    pthread_mutex_lock(in_use->mysys_var->current_mutex);
-            signalled= 1;
-	    pthread_cond_broadcast(in_use->mysys_var->current_cond);
-	    pthread_mutex_unlock(in_use->mysys_var->current_mutex);
-	  }
-	  pthread_mutex_unlock(&in_use->mysys_var->mutex);
+          if (!in_use->killed)
+          {
+            in_use->killed= THD::KILL_CONNECTION;
+            pthread_mutex_lock(&in_use->mysys_var->mutex);
+            if (in_use->mysys_var->current_cond)
+            {
+              pthread_mutex_lock(in_use->mysys_var->current_mutex);
+              signalled= 1;
+              pthread_cond_broadcast(in_use->mysys_var->current_cond);
+              pthread_mutex_unlock(in_use->mysys_var->current_mutex);
+            }
+            pthread_mutex_unlock(&in_use->mysys_var->mutex);
+          }
+          /*
+            Don't abort locks. Instead give the delayed insert thread
+            time to finish it's inserts and die gracefully. 
+          */
+          continue;
         }
         /*
 	  Now we must abort all tables locks used by this thread

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2009-11-30 21:37:27 +0000
+++ b/sql/sql_class.cc	2009-12-04 15:12:22 +0000
@@ -2046,7 +2046,7 @@ bool select_export::send_data(List<Item>
                             ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
                             ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
                             "string", printable_buff,
-                            item->name, row_count);
+                            item->name, (ulong) row_count);
       }
       cvt_str.length(bytes);
       res= &cvt_str;

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2009-11-30 21:37:27 +0000
+++ b/sql/sql_insert.cc	2009-12-04 15:12:22 +0000
@@ -2618,7 +2618,7 @@ bool Delayed_insert::handle_inserts(void
       or if another thread is removing the current table definition
       from the table cache.
     */
-    my_error(ER_DELAYED_CANT_CHANGE_LOCK,MYF(ME_FATALERROR),
+    my_error(ER_DELAYED_CANT_CHANGE_LOCK, MYF(ME_FATALERROR | ME_NOREFRESH),
              table->s->table_name.str);
     goto err;
   }
@@ -2791,10 +2791,11 @@ bool Delayed_insert::handle_inserts(void
 	query_cache_invalidate3(&thd, table, 1);
 	if (thr_reschedule_write_lock(*thd.lock->locks))
 	{
-    /* This is not known to happen. */
-    my_error(ER_DELAYED_CANT_CHANGE_LOCK,MYF(ME_FATALERROR),
-             table->s->table_name.str);
-    goto err;
+          /* This is not known to happen. */
+          my_error(ER_DELAYED_CANT_CHANGE_LOCK,
+                   MYF(ME_FATALERROR | ME_NOREFRESH),
+                   table->s->table_name.str);
+          goto err;
 	}
 	if (!using_bin_log)
 	  table->file->extra(HA_EXTRA_WRITE_CACHE);

=== modified file 'storage/federatedx/ha_federatedx.cc'
--- a/storage/federatedx/ha_federatedx.cc	2009-11-30 21:37:27 +0000
+++ b/storage/federatedx/ha_federatedx.cc	2009-12-03 11:34:11 +0000
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2008, Patrick Galbraith 
+Copyright (c) 2008-2009, Patrick Galbraith & Antony Curtis
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -308,7 +308,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 */
 
 
-#define MYSQL_SERVER 1q
+#define MYSQL_SERVER 1
 #include "mysql_priv.h"
 #include <mysql/plugin.h>
 
@@ -1627,7 +1627,13 @@ static int free_server(federatedx_txn *t
   {
     MEM_ROOT mem_root;
 
-    txn->close(server);
+    if (!txn)
+    {
+      federatedx_txn tmp_txn;
+      tmp_txn.close(server);
+    }
+    else
+      txn->close(server);
 
     DBUG_ASSERT(server->io_count == 0);
 
@@ -1785,21 +1791,25 @@ int ha_federatedx::close(void)
   if (stored_result)
     retval= free_result();
 
-  /* Disconnect from mysql. thd may be null during refresh */
-  txn= thd ? get_txn(thd, true) : new federatedx_txn();
+  /* Disconnect from mysql */
+  if (!thd || !(txn= get_txn(thd, true)))
+  {
+    federatedx_txn tmp_txn;
+
+    tmp_txn.release(&io);
 
-  if (txn)
+    DBUG_ASSERT(io == NULL);
+    
+    if ((error= free_share(&tmp_txn, share)))
+      retval= error;
+  }
+  else
   {
     txn->release(&io);
-    
     DBUG_ASSERT(io == NULL);
 
     if ((error= free_share(txn, share)))
       retval= error;
-
-    if (!thd)
-      delete txn;
-
   }
   DBUG_RETURN(retval);
 }
@@ -2793,14 +2803,16 @@ int ha_federatedx::rnd_end()
 int ha_federatedx::free_result()
 {
   int error;
+  federatedx_io *tmp_io= 0, **iop;
   DBUG_ASSERT(stored_result);
-  if ((error= txn->acquire(share, FALSE, &io)))
+  if (!*(iop= &io) && (error= txn->acquire(share, TRUE, (iop= &tmp_io))))
   {
     DBUG_ASSERT(0);                             // Fail when testing
     return error;
   }
-  io->free_result(stored_result);
+  (*iop)->free_result(stored_result);
   stored_result= 0;
+  txn->release(&tmp_io);
   return 0;
 }
 
@@ -2985,7 +2997,7 @@ int ha_federatedx::info(uint flag)
 {
   char error_buffer[FEDERATEDX_QUERY_BUFFER_SIZE];
   uint error_code;
-  federatedx_io *tmp_io= 0;
+  federatedx_io *tmp_io= 0, **iop= 0;
   DBUG_ENTER("ha_federatedx::info");
 
   error_code= ER_QUERY_ON_FOREIGN_DATA_SOURCE;
@@ -2993,7 +3005,7 @@ int ha_federatedx::info(uint flag)
   /* we want not to show table status if not needed to do so */
   if (flag & (HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO))
   {
-    if ((error_code= txn->acquire(share, TRUE, &tmp_io)))
+    if (!*(iop= &io) && (error_code= txn->acquire(share, TRUE, (iop= &tmp_io))))
       goto fail;
   }
 
@@ -3006,13 +3018,13 @@ int ha_federatedx::info(uint flag)
     if (flag & HA_STATUS_CONST)
       stats.block_size= 4096;
 
-    if (tmp_io->table_metadata(&stats, share->table_name,
+    if ((*iop)->table_metadata(&stats, share->table_name,
                                share->table_name_length, flag))
       goto error;
   }
 
   if (flag & HA_STATUS_AUTO)
-    stats.auto_increment_value= tmp_io->last_insert_id();
+    stats.auto_increment_value= (*iop)->last_insert_id();
 
   /*
     If ::info created it's own transaction, close it. This happens in case
@@ -3023,10 +3035,10 @@ int ha_federatedx::info(uint flag)
   DBUG_RETURN(0);
 
 error:
-  if (tmp_io)
+  if (iop && *iop)
   {
     my_sprintf(error_buffer, (error_buffer, ": %d : %s",
-                              tmp_io->error_code(), tmp_io->error_str()));
+                              (*iop)->error_code(), (*iop)->error_str()));
     my_error(error_code, MYF(0), error_buffer);
   }
   else

=== modified file 'strings/ctype-uca.c'
--- a/strings/ctype-uca.c	2009-11-30 12:42:24 +0000
+++ b/strings/ctype-uca.c	2009-12-03 11:34:11 +0000
@@ -36,6 +36,12 @@
 #include "m_string.h"
 #include "m_ctype.h"
 
+
+#define MY_UCA_CNT_FLAG_SIZE 4096
+#define MY_UCA_CNT_FLAG_MASK 4095
+#define MY_UCA_CNT_HEAD 1
+#define MY_UCA_CNT_TAIL 2
+
 #ifdef HAVE_UCA_COLLATIONS
 
 #define MY_UCA_NPAGES 256
@@ -6756,16 +6762,6 @@ typedef struct my_uca_scanner_handler_st
 
 static uint16 nochar[]= {0,0};
 
-
-#define MY_UCA_CNT_FLAG_SIZE 4096
-#define MY_UCA_CNT_FLAG_MASK 4095
-
-#define MY_UCA_CNT_HEAD 1
-#define MY_UCA_CNT_TAIL 2
-
-
-
-
 /********** Helper functions to handle contraction ************/
 
 
@@ -6836,85 +6832,6 @@ my_uca_alloc_contractions(CHARSET_INFO *
   return 0;
 }
 
-
-/**
-  Check if UCA data has contractions (public version)
-
-  @cs       Pointer to CHARSET_INFO data
-  @retval   0 - no contraction, 1 - have contractions.
-*/
-
-my_bool
-my_uca_have_contractions(CHARSET_INFO *cs)
-{
-  return cs->contractions != NULL;
-}
-
-
-/**
-  Check if a character can be contraction head
-  
-  @cs       Pointer to CHARSET_INFO data
-  @wc       Code point
-  
-  @retval   0 - cannot be contraction head
-  @retval   1 - can be contraction head
-*/
-
-my_bool
-my_uca_can_be_contraction_head(CHARSET_INFO *cs, my_wc_t wc)
-{
-  return cs->contractions->flags[wc & MY_UCA_CNT_FLAG_MASK] & MY_UCA_CNT_HEAD;
-}
-
-
-/**
-  Check if a character can be contraction tail
-  
-  @cs       Pointer to CHARSET_INFO data
-  @wc       Code point
-  
-  @retval   0 - cannot be contraction tail
-  @retval   1 - can be contraction tail
-*/
-
-my_bool
-my_uca_can_be_contraction_tail(CHARSET_INFO *cs, my_wc_t wc)
-{
-  return cs->contractions->flags[wc & MY_UCA_CNT_FLAG_MASK] & MY_UCA_CNT_TAIL;
-}
-
-
-/**
-  Find a contraction and return its weight array
-  
-  @cs       Pointer to CHARSET data
-  @wc1      First character
-  @wc2      Second character
-  
-  @return   Weight array
-  @retval   NULL - no contraction found
-  @retval   ptr  - contraction weight array
-*/
-
-uint16 *
-my_uca_contraction2_weight(CHARSET_INFO *cs, my_wc_t wc1, my_wc_t wc2)
-{
-  MY_CONTRACTIONS *list= cs->contractions;
-  MY_CONTRACTION *c, *last;
-  for (c= list->item, last= &list->item[list->nitems]; c < last; c++)
-  {
-    if (c->ch[0] == wc1 && c->ch[1] == wc2)
-    {
-      return c->weight;
-    }
-  }
-  return NULL;
-}
-
-
-
-
 #ifdef HAVE_CHARSET_ucs2
 /*
   Initialize collation weight scanner
@@ -9607,3 +9524,78 @@ CHARSET_INFO my_charset_utf8_croatian_uc
 #endif /* HAVE_CHARSET_utf8 */
 
 #endif /* HAVE_UCA_COLLATIONS */
+
+/**
+  Check if UCA data has contractions (public version)
+
+  @cs       Pointer to CHARSET_INFO data
+  @retval   0 - no contraction, 1 - have contractions.
+*/
+
+my_bool
+my_uca_have_contractions(CHARSET_INFO *cs)
+{
+  return cs->contractions != NULL;
+}
+
+/**
+  Check if a character can be contraction head
+  
+  @cs       Pointer to CHARSET_INFO data
+  @wc       Code point
+  
+  @retval   0 - cannot be contraction head
+  @retval   1 - can be contraction head
+*/
+
+my_bool
+my_uca_can_be_contraction_head(CHARSET_INFO *cs, my_wc_t wc)
+{
+  return cs->contractions->flags[wc & MY_UCA_CNT_FLAG_MASK] & MY_UCA_CNT_HEAD;
+}
+
+
+/**
+  Check if a character can be contraction tail
+  
+  @cs       Pointer to CHARSET_INFO data
+  @wc       Code point
+  
+  @retval   0 - cannot be contraction tail
+  @retval   1 - can be contraction tail
+*/
+
+my_bool
+my_uca_can_be_contraction_tail(CHARSET_INFO *cs, my_wc_t wc)
+{
+  return cs->contractions->flags[wc & MY_UCA_CNT_FLAG_MASK] & MY_UCA_CNT_TAIL;
+}
+
+
+/**
+  Find a contraction and return its weight array
+  
+  @cs       Pointer to CHARSET data
+  @wc1      First character
+  @wc2      Second character
+  
+  @return   Weight array
+  @retval   NULL - no contraction found
+  @retval   ptr  - contraction weight array
+*/
+
+uint16 *
+my_uca_contraction2_weight(CHARSET_INFO *cs, my_wc_t wc1, my_wc_t wc2)
+{
+  MY_CONTRACTIONS *list= cs->contractions;
+  MY_CONTRACTION *c, *last;
+  for (c= list->item, last= &list->item[list->nitems]; c < last; c++)
+  {
+    if (c->ch[0] == wc1 && c->ch[1] == wc2)
+    {
+      return c->weight;
+    }
+  }
+  return NULL;
+}
+

=== modified file 'strings/ctype-ucs2.c'
--- a/strings/ctype-ucs2.c	2009-11-30 12:42:24 +0000
+++ b/strings/ctype-ucs2.c	2009-12-03 12:02:37 +0000
@@ -1498,6 +1498,14 @@ void my_hash_sort_ucs2_bin(CHARSET_INFO 
   }
 }
 
+
+static inline my_wc_t
+ucs2_to_wc(const uchar *ptr)
+{
+  return (((uint) ptr[0]) << 8) + ptr[1];
+}
+
+
 /*
 ** Calculate min_str and max_str that ranges a LIKE string.
 ** Arguments:
@@ -1531,6 +1539,7 @@ my_bool my_like_range_ucs2(CHARSET_INFO 
   for ( ; ptr + 1 < end && min_str + 1 < min_end && charlen > 0
         ; ptr+=2, charlen--)
   {
+    my_wc_t wc;
     if (ptr[0] == '\0' && ptr[1] == escape && ptr + 1 < end)
     {
       ptr+=2;					/* Skip escape */
@@ -1567,9 +1576,9 @@ fill_max_and_min:
     }
 
     if (have_contractions && ptr + 3 < end &&
-        ptr[0] == '\0' &&
-        my_uca_can_be_contraction_head(cs, (uchar) ptr[1]))
+        my_uca_can_be_contraction_head(cs, (wc= ucs2_to_wc((uchar*) ptr))))
     {
+      my_wc_t wc2;
       /* Contraction head found */
       if (ptr[2] == '\0' && (ptr[3] == w_one || ptr[3] == w_many))
       {
@@ -1581,9 +1590,8 @@ fill_max_and_min:
         Check if the second letter can be contraction part,
         and if two letters really produce a contraction.
       */
-      if (ptr[2] == '\0' &&
-          my_uca_can_be_contraction_tail(cs, (uchar) ptr[3]) &&
-          my_uca_contraction2_weight(cs,(uchar) ptr[1], (uchar) ptr[3]))
+      if (my_uca_can_be_contraction_tail(cs, (wc2= ucs2_to_wc((uchar*) ptr + 2))) &&
+          my_uca_contraction2_weight(cs, wc , wc2))
       {
         /* Contraction found */
         if (charlen == 1 || min_str + 2 >= min_end)

=== modified file 'unittest/mysys/Makefile.am'
--- a/unittest/mysys/Makefile.am	2009-11-26 08:44:38 +0000
+++ b/unittest/mysys/Makefile.am	2009-12-03 11:19:05 +0000
@@ -24,7 +24,7 @@ LDADD 		= $(top_builddir)/unittest/mytap
 		  $(top_builddir)/strings/libmystrings.a
 
 EXTRA_DIST       = CMakeLists.txt 
-noinst_PROGRAMS  = bitmap-t base64-t lf-t waiting_threads-t
+noinst_PROGRAMS  = bitmap-t base64-t my_atomic-t lf-t waiting_threads-t
 
 if NEED_THREAD
 # my_atomic-t is used to check thread functions, so it is safe to