List:Commits« Previous MessageNext Message »
From:Guilhem Bichot Date:February 10 2011 1:58pm
Subject:[Resend] bzr commit into mysql-5.5 branch (guilhem.bichot:3315) Bug#59894
View as plain text  
[This commit e-mail is a repeat.]

#At file:///home/mysql_src/bzrrepos_new/5.5-bugteam/ based on
revid:anitha.gopi@stripped

 3315 Guilhem Bichot	2011-02-10
      Fix for BUG#59894
      "set optimizer_switch to e or d causes invalid memory writes/valgrind warnings":
      due to prefix support, the argument "e" was overwritten with its full value
      "engine_condition_pushdown", which caused a buffer overrun.
      This was wrong usage of find_type(); other wrong usages are fixed here too.
      Please start reading with the comment of typelib.c.
     @ client/mysqldump.c
        A bug: find_type() expects a bitmap as 3rd argument
        (each bit is a flag controlling a behaviour of the function);
        here it was instead passed the length of the string to search!
        That could give random behaviour of find_type()
        depending on the string.
        We rather need to pass a correct flag to find_type().
        The correct flag is FIND_TYPE_BASIC (0).
        Flag 8 is not needed as buff cannot have a comma (see how buff is filled).
        Flag 1 looks like a superfluous restriction.
        Flag 4 is not user-friendly (why use
        --compatible=2 rather than --compatible=mysql40 ?, and
        we probably not commit to "2" always meaning "mysql40"
        until the end of times).
        Copyright: fix year and FSF address.
     @ include/mysql.h.pp
        This isn't a problematic API change as we go from char* to const char*:
        existing code will run unchanged.
     @ include/typelib.h
        named constants. Not an enum to not significantly change
        the declaration of find_type() which would be an API change
        (typelib.h is included in mysql.h).
     @ mysql-test/r/mysqldump.result
        correct result (see the two requested modes in SQL_MODE)
     @ mysql-test/suite/sys_vars/t/optimizer_switch_basic.test
        test for BUG#59894. The second SET used to crash.
     @ mysql-test/t/mysqldump.test
        we had no test for multiple modes in --compatible, which is
        supported according to --help
     @ mysys/typelib.c
        Fix for BUG#59894. parse_name() is asked to match "e" with a row
        of the TYPELIB (the TYPELIB lists permitted flags of optimizer_switch;
        and comes from optimizer_switch_names[] of sys_vars.cc).
        find_type() is capable of supporting prefixes, but if it is not
        passed flag 2 in third argument, it will overwrite its first
        argument (the string to search for) with the complete name,
        here overwriting "e" with "engine_condition_pushdown". But
        as this "e" was a buffer allocated in an Item, it was not big
        enough to host the longer name, thus the crash.
        We don't need to know the complete flag's name; the output used
        from find_type() is just the flag's number (== function's return
        code). So we can pass flag 2 to find_type() in parse_name().
        After doing this fix and the other fixes in this patch, all usages
        of find_type() were using flag 2; in most usages the string to search for,
        is not guaranteed to be long enough to host the complete name
        (it is either directly from argv, or from alloc_root/my_malloc
        done in an earlier call).
        Thus, flag 2 is here made implicit: callers need not pass it anymore,
        it is always automatically turned on.
        This allows to eliminate an oddity: parse_name() took a const char**,
        and then removed "const" before calling find_type(), which could
        theoretically modify the pointed data, thus lying on constness.
        Last, constants for find_type() are now named.
     @ sql-common/client.c
        Two bugs:
        1) The enum was not in sync with the array (due to a bad porting of WL 1054;
        the extra OPT_ values are about options present in 5.1 and deleted in 5.5);
        added a compile_time_assert() to make sure this doesn't happen again
        2) find_type() was writing past the end of opt_arg; as opt_arg was allocated
        with alloc_root() with no extra space, this was an overrun; it could be seen
        when
        ** building with -DWITH_VALGRIND -DHAVE_purify -DEXTRA_DEBUG
        ** making execution go through the faulty code; this faulty
        code is executed only if the client asks to read a configuration
        file like this:
          mysql_options(mysql, MYSQL_READ_DEFAULT_FILE, "/tmp/cnf.cnf");
        so by adding such line to the start of mysql_client_test.c::client_connect(),
        we could see the valgrind warning:
        ==30548== Invalid write of size 1
        ==30548==    at 0x4C2624C: strcpy (mc_replace_strmem.c:303)
        ==30548==    by 0x48DC29: find_type (typelib.c:120)
        ==30548==    by 0x465686: mysql_read_default_options (client.c:1344)
        ==30548==    by 0x46830F: mysql_real_connect (client.c:2971)
        ==30548==    by 0x409339: client_connect (mysql_client_test.c:331)
        ==30548==    by 0x463A7F: main (mysql_client_test.c:19902)
        ==30548==  Address 0x61875ad is 0 bytes after a block of size 29 alloc'd
        ==30548==    at 0x4C25153: malloc (vg_replace_malloc.c:195)
        ==30548==    by 0x49BFF1: my_malloc (my_malloc.c:38)
        ==30548==    by 0x49C65C: alloc_root (my_alloc.c:166)
        ==30548==    by 0x48EF97: handle_default_option (default.c:381)
        ==30548==    by 0x49068C: search_default_file_with_ext (default.c:992)
        ==30548==    by 0x48F929: search_default_file (default.c:670)
        ==30548==    by 0x48EDC4: my_search_option_files (default.c:312)
        ==30548==    by 0x48F4B1: my_load_defaults (default.c:576)
        ==30548==    by 0x46517A: mysql_read_default_options (client.c:1207)
        ==30548==    by 0x46830F: mysql_real_connect (client.c:2971)
        ==30548==    by 0x409339: client_connect (mysql_client_test.c:331)
        ==30548==    by 0x463A7F: main (mysql_client_test.c:19902)
        This is fixed by having find_type() not overwrite anymore.
     @ sql/sql_help.cc
        cast not needed anymore.
     @ sql/table.cc
        cast not needed anymore.

    modified:
      client/mysqladmin.cc
      client/mysqldump.c
      client/mysqltest.cc
      include/mysql.h.pp
      include/typelib.h
      mysql-test/r/mysqldump.result
      mysql-test/suite/sys_vars/r/optimizer_switch_basic.result
      mysql-test/suite/sys_vars/t/optimizer_switch_basic.test
      mysql-test/t/mysqldump.test
      mysys/default.c
      mysys/my_getopt.c
      mysys/typelib.c
      sql-common/client.c
      sql/sql_db.cc
      sql/sql_handler.cc
      sql/sql_help.cc
      sql/strfunc.cc
      sql/table.cc
      storage/myisam/myisamchk.c
      storage/myisammrg/myrg_open.c
=== modified file 'client/mysqladmin.cc'
--- a/client/mysqladmin.cc	2011-01-16 03:59:05 +0000
+++ b/client/mysqladmin.cc	2011-02-10 13:57:46 +0000
@@ -369,7 +369,8 @@ int main(int argc,char *argv[])
       /* Return 0 if all commands are PING */
       for (; argc > 0; argv++, argc--)
       {
-        if (find_type(argv[0], &command_typelib, 2) != ADMIN_PING)
+        if (find_type(argv[0], &command_typelib, FIND_TYPE_BASIC) !=
+            ADMIN_PING)
         {
           error= 1;
           break;
@@ -592,7 +593,7 @@ static int execute_commands(MYSQL *mysql
 
   for (; argc > 0 ; argv++,argc--)
   {
-    switch (find_type(argv[0],&command_typelib,2)) {
+    switch (find_type(argv[0],&command_typelib, FIND_TYPE_BASIC)) {
     case ADMIN_CREATE:
     {
       char buff[FN_REFLEN+20];
@@ -931,7 +932,7 @@ static int execute_commands(MYSQL *mysql
 
       if (typed_password[0])
       {
-        bool old= (find_type(argv[0], &command_typelib, 2) ==
+        bool old= (find_type(argv[0], &command_typelib, FIND_TYPE_BASIC) ==
                    ADMIN_OLD_PASSWORD);
 #ifdef __WIN__
         size_t pw_len= strlen(typed_password);

=== modified file 'client/mysqldump.c'
--- a/client/mysqldump.c	2011-01-16 03:59:05 +0000
+++ b/client/mysqldump.c	2011-02-10 13:57:46 +0000
@@ -1,17 +1,21 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights
+   reserved.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 of the License.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; version 2 of
+   the License.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+   02110-1301  USA
+*/
 
 /* mysqldump.c  - Dump a tables contents and format to an ASCII file
 **
@@ -4644,7 +4648,7 @@ static ulong find_set(TYPELIB *lib, cons
       for (; pos != end && *pos != ','; pos++) ;
       var_len= (uint) (pos - start);
       strmake(buff, start, min(sizeof(buff) - 1, var_len));
-      find= find_type(buff, lib, var_len);
+      find= find_type(buff, lib, FIND_TYPE_BASIC);
       if (!find)
       {
         *err_pos= (char*) start;

=== modified file 'client/mysqltest.cc'
--- a/client/mysqltest.cc	2011-01-26 18:33:53 +0000
+++ b/client/mysqltest.cc	2011-02-10 13:57:46 +0000
@@ -8017,7 +8017,7 @@ void get_command_type(struct st_command*
 
   save= command->query[command->first_word_len];
   command->query[command->first_word_len]= 0;
-  type= find_type(command->query, &command_typelib, 1+2);
+  type= find_type(command->query, &command_typelib, FIND_TYPE_NO_PREFIX);
   command->query[command->first_word_len]= save;
   if (type > 0)
   {

=== modified file 'include/mysql.h.pp'
--- a/include/mysql.h.pp	2010-10-04 12:42:16 +0000
+++ b/include/mysql.h.pp	2011-02-10 13:57:46 +0000
@@ -227,7 +227,7 @@ typedef struct st_typelib {
 extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position);
 extern int find_type_or_exit(const char *x, TYPELIB *typelib,
                              const char *option);
-extern int find_type(char *x, const TYPELIB *typelib, unsigned int full_name);
+extern int find_type(const char *x, const TYPELIB *typelib, unsigned int flags);
 extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
 extern const char *get_type(TYPELIB *typelib,unsigned int nr);
 extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from);

=== modified file 'include/typelib.h'
--- a/include/typelib.h	2010-07-05 16:20:46 +0000
+++ b/include/typelib.h	2011-02-10 13:57:46 +0000
@@ -1,18 +1,21 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights
+   reserved.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 of the License.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; version 2 of
+   the License.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+   02110-1301  USA
+*/
 
 #ifndef _typelib_h
 #define _typelib_h
@@ -29,7 +32,17 @@ typedef struct st_typelib {	/* Different
 extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position);
 extern int find_type_or_exit(const char *x, TYPELIB *typelib,
                              const char *option);
-extern int find_type(char *x, const TYPELIB *typelib, unsigned int full_name);
+#define FIND_TYPE_BASIC           0
+/** makes @c find_type() require the whole name, no prefix */
+#define FIND_TYPE_NO_PREFIX      (1 << 0)
+/** always implicitely on, so unused, but old code may pass it */
+#define FIND_TYPE_NO_OVERWRITE   (1 << 1)
+/** makes @c find_type() accept a number */
+#define FIND_TYPE_ALLOW_NUMBER   (1 << 2)
+/** makes @c find_type() treat ',' as terminator */
+#define FIND_TYPE_COMMA_TERM     (1 << 3)
+
+extern int find_type(const char *x, const TYPELIB *typelib, unsigned int flags);
 extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
 extern const char *get_type(TYPELIB *typelib,unsigned int nr);
 extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from);

=== modified file 'mysql-test/r/mysqldump.result'
--- a/mysql-test/r/mysqldump.result	2011-01-14 14:41:00 +0000
+++ b/mysql-test/r/mysqldump.result	2011-02-10 13:57:46 +0000
@@ -4593,3 +4593,35 @@ DROP TABLE `comment_table`;
 #
 # End of 5.1 tests
 #
+#
+# Verify that two modes can be given in --compatible;
+# and are reflected in SET SQL_MODE in the mysqldump output.
+# Also verify that a prefix of the mode's name is enough.
+#
+CREATE TABLE t1 (a INT);
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE,
SQL_MODE='NO_AUTO_VALUE_ON_ZERO,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+DROP TABLE IF EXISTS `t1`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+);
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+LOCK TABLES `t1` WRITE;
+/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+DROP TABLE t1;

=== modified file 'mysql-test/suite/sys_vars/r/optimizer_switch_basic.result'
--- a/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result	2010-01-29 06:33:00 +0000
+++ b/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result	2011-02-10 13:57:46 +0000
@@ -60,6 +60,13 @@ set session optimizer_switch="index_merg
 ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge'
 set session optimizer_switch="foobar";
 ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'foobar'
+#
+# Bug#59894 set optimizer_switch to e or d causes invalid
+# memory writes/valgrind warnings
+
+set global optimizer_switch = 'd';
+set global optimizer_switch = 'e';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'e'
 SET @@global.optimizer_switch = @start_global_value;
 SELECT @@global.optimizer_switch;
 @@global.optimizer_switch

=== modified file 'mysql-test/suite/sys_vars/t/optimizer_switch_basic.test'
--- a/mysql-test/suite/sys_vars/t/optimizer_switch_basic.test	2010-01-29 06:33:00 +0000
+++ b/mysql-test/suite/sys_vars/t/optimizer_switch_basic.test	2011-02-10 13:57:46 +0000
@@ -46,5 +46,13 @@ set session optimizer_switch="index_merg
 --error ER_WRONG_VALUE_FOR_VAR
 set session optimizer_switch="foobar";
 
+--echo #
+--echo # Bug#59894 set optimizer_switch to e or d causes invalid
+--echo # memory writes/valgrind warnings
+--echo
+set global optimizer_switch = 'd'; # means default
+--error ER_WRONG_VALUE_FOR_VAR
+set global optimizer_switch = 'e';
+
 SET @@global.optimizer_switch = @start_global_value;
 SELECT @@global.optimizer_switch;

=== modified file 'mysql-test/t/mysqldump.test'
--- a/mysql-test/t/mysqldump.test	2011-01-14 14:41:00 +0000
+++ b/mysql-test/t/mysqldump.test	2011-02-10 13:57:46 +0000
@@ -2182,5 +2182,15 @@ DROP TABLE `comment_table`;
 --echo # End of 5.1 tests
 --echo #
 
+--echo #
+--echo # Verify that two modes can be given in --compatible;
+--echo # and are reflected in SET SQL_MODE in the mysqldump output.
+--echo # Also verify that a prefix of the mode's name is enough.
+--echo #
+CREATE TABLE t1 (a INT);
+# no_t = no_table_options; no_f = no_field_options
+--exec $MYSQL_DUMP --compatible=no_t,no_f --skip-comments test
+DROP TABLE t1;
+
 # Wait till we reached the initial number of concurrent sessions
 --source include/wait_until_count_sessions.inc

=== modified file 'mysys/default.c'
--- a/mysys/default.c	2011-01-17 07:44:37 +0000
+++ b/mysys/default.c	2011-02-10 13:57:46 +0000
@@ -1,17 +1,21 @@
-/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights
+   reserved.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 of the License.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; version 2 of
+   the License.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+   02110-1301  USA
+*/
 
 /****************************************************************************
  Add all options from files named "group".cnf from the default_directories
@@ -376,7 +380,7 @@ static int handle_default_option(void *i
   if (!option)
     return 0;
 
-  if (find_type((char *)group_name, ctx->group, 3))
+  if (find_type((char *)group_name, ctx->group, FIND_TYPE_NO_PREFIX))
   {
     if (!(tmp= alloc_root(ctx->alloc, strlen(option) + 1)))
       return 1;

=== modified file 'mysys/my_getopt.c'
--- a/mysys/my_getopt.c	2011-01-17 07:44:37 +0000
+++ b/mysys/my_getopt.c	2011-02-10 13:57:46 +0000
@@ -1,17 +1,21 @@
-/* Copyright (C) 2002-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights
+   reserved.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 of the License.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; version 2 of
+   the License.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+   02110-1301  USA
+*/
 
 #include <my_global.h>
 #include <m_string.h>
@@ -695,7 +699,7 @@ static int setval(const struct my_option
       break;
     case GET_ENUM:
       {
-        int type= find_type(argument, opts->typelib, 2);
+        int type= find_type(argument, opts->typelib, FIND_TYPE_BASIC);
         if (type == 0)
         {
           /*

=== modified file 'mysys/typelib.c'
--- a/mysys/typelib.c	2010-03-13 21:17:47 +0000
+++ b/mysys/typelib.c	2011-02-10 13:57:46 +0000
@@ -1,17 +1,21 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights
+   reserved.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 of the License.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; version 2 of
+   the License.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+   02110-1301  USA
+*/
 
 /* Functions to handle typelib */
 
@@ -27,7 +31,7 @@ int find_type_or_exit(const char *x, TYP
   int res;
   const char **ptr;
 
-  if ((res= find_type((char *) x, typelib, 2)) <= 0)
+  if ((res= find_type((char *) x, typelib, FIND_TYPE_BASIC)) <= 0)
   {
     ptr= typelib->type_names;
     if (!*x)
@@ -49,15 +53,11 @@ int find_type_or_exit(const char *x, TYP
 
   @param x              String to find
   @param lib            TYPELIB (struct of pointer to values + count)
-  @param full_name      bitmap of what to do
-                        If & 1 accept only whole names
-                        If & 2 don't expand if half field
-                        If & 4 allow #number# as type
-                        If & 8 use ',' as string terminator
-
-  @note
-  If part, uniq field is found and full_name == 0 then x is expanded
-  to full field.
+  @param flags          flags to tune behaviour: a combination of
+                        FIND_TYPE_NO_PREFIX
+                        FIND_TYPE_ALLOW_NUMBER
+                        FIND_TYPE_COMMA_TERM. FIND_TYPE_NO_OVERWRITE can be
+                        passed but is superfluous (is always implicitely on).
 
   @retval
     -1  Too many matching values
@@ -68,15 +68,17 @@ int find_type_or_exit(const char *x, TYP
 */
 
 
-int find_type(char *x, const TYPELIB *typelib, uint full_name)
+int find_type(const char *x, const TYPELIB *typelib, uint flags)
 {
   int find,pos;
   int UNINIT_VAR(findpos);                       /* guarded by find */
-  reg1 char * i;
+  reg1 const char *i;
   reg2 const char *j;
   DBUG_ENTER("find_type");
   DBUG_PRINT("enter",("x: '%s'  lib: 0x%lx", x, (long) typelib));
 
+  DBUG_ASSERT(!(flags & ~(FIND_TYPE_NO_PREFIX | FIND_TYPE_ALLOW_NUMBER |
+                          FIND_TYPE_NO_OVERWRITE | FIND_TYPE_COMMA_TERM)));
   if (!typelib->count)
   {
     DBUG_PRINT("exit",("no count"));
@@ -86,24 +88,26 @@ int find_type(char *x, const TYPELIB *ty
   for (pos=0 ; (j=typelib->type_names[pos]) ; pos++)
   {
     for (i=x ; 
-    	*i && (!(full_name & 8) || !is_field_separator(*i)) &&
+    	*i && (!(flags & FIND_TYPE_COMMA_TERM) || !is_field_separator(*i))
&&
         my_toupper(&my_charset_latin1,*i) == 
     		my_toupper(&my_charset_latin1,*j) ; i++, j++) ;
     if (! *j)
     {
       while (*i == ' ')
 	i++;					/* skip_end_space */
-      if (! *i || ((full_name & 8) && is_field_separator(*i)))
+      if (! *i || ((flags & FIND_TYPE_COMMA_TERM) && is_field_separator(*i)))
 	DBUG_RETURN(pos+1);
     }
-    if ((!*i && (!(full_name & 8) || !is_field_separator(*i))) && 
-        (!*j || !(full_name & 1)))
+    if ((!*i &&
+         (!(flags & FIND_TYPE_COMMA_TERM) || !is_field_separator(*i))) &&
+        (!*j || !(flags & FIND_TYPE_NO_PREFIX)))
     {
       find++;
       findpos=pos;
     }
   }
-  if (find == 0 && (full_name & 4) && x[0] == '#' &&
strend(x)[-1] == '#' &&
+  if (find == 0 && (flags & FIND_TYPE_ALLOW_NUMBER) && x[0] == '#'
&&
+      strend(x)[-1] == '#' &&
       (findpos=atoi(x+1)-1) >= 0 && (uint) findpos < typelib->count)
     find=1;
   else if (find == 0 || ! x[0])
@@ -111,13 +115,11 @@ int find_type(char *x, const TYPELIB *ty
     DBUG_PRINT("exit",("Couldn't find type"));
     DBUG_RETURN(0);
   }
-  else if (find != 1 || (full_name & 1))
+  else if (find != 1 || (flags & FIND_TYPE_NO_PREFIX))
   {
     DBUG_PRINT("exit",("Too many possybilities"));
     DBUG_RETURN(-1);
   }
-  if (!(full_name & 2))
-    (void) strmov(x,typelib->type_names[findpos]);
   DBUG_RETURN(findpos+1);
 } /* find_type */
 
@@ -192,7 +194,7 @@ my_ulonglong find_typeset(char *x, TYPEL
       x++;
     if (x[0] && x[1])      /* skip separator if found */
       x++;
-    if ((find= find_type(i, lib, 2 | 8) - 1) < 0)
+    if ((find= find_type(i, lib, FIND_TYPE_COMMA_TERM) - 1) < 0)
       DBUG_RETURN(0);
     result|= (ULL(1) << find);
   }
@@ -276,7 +278,7 @@ static TYPELIB on_off_default_typelib= {
 static uint parse_name(const TYPELIB *lib, const char **strpos, const char *end)
 {
   const char *pos= *strpos;
-  uint find= find_type((char*)pos, lib, 8);
+  uint find= find_type(pos, lib, FIND_TYPE_COMMA_TERM);
   for (; pos != end && *pos != '=' && *pos !=',' ; pos++);
   *strpos= pos;
   return find;

=== modified file 'sql-common/client.c'
--- a/sql-common/client.c	2011-01-31 15:32:57 +0000
+++ b/sql-common/client.c	2011-02-10 13:57:46 +0000
@@ -1,17 +1,21 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights
+   reserved.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 of the License.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; version 2 of
+   the License.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+   02110-1301  USA
+*/
 
 /*
   This file is included by both libmysql.c (the MySQL client C API)
@@ -1145,10 +1149,10 @@ enum option_id {
   OPT_ssl_key, OPT_ssl_cert, OPT_ssl_ca, OPT_ssl_capath, 
   OPT_character_sets_dir, OPT_default_character_set, OPT_interactive_timeout, 
   OPT_connect_timeout, OPT_local_infile, OPT_disable_local_infile, 
-  OPT_replication_probe, OPT_enable_reads_from_master, OPT_repl_parse_query,
   OPT_ssl_cipher, OPT_max_allowed_packet, OPT_protocol, OPT_shared_memory_base_name, 
   OPT_multi_results, OPT_multi_statements, OPT_multi_queries, OPT_secure_auth, 
   OPT_report_data_truncation, OPT_plugin_dir, OPT_default_auth, 
+  OPT_keep_this_one_last
 };
 
 static TYPELIB option_types={array_elements(default_options)-1,
@@ -1198,6 +1202,9 @@ void mysql_read_default_options(struct s
   DBUG_ENTER("mysql_read_default_options");
   DBUG_PRINT("enter",("file: %s  group: %s",filename,group ? group :"NULL"));
 
+  compile_time_assert(OPT_keep_this_one_last ==
+                      array_elements(default_options));
+
   argc=1; argv=argv_buff; argv_buff[0]= (char*) "client";
   groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0;
 
@@ -1222,7 +1229,7 @@ void mysql_read_default_options(struct s
 	/* Change all '_' in variable name to '-' */
 	for (end= *option ; *(end= strcend(end,'_')) ; )
 	  *end= '-';
-	switch (find_type(*option+2,&option_types,2)) {
+	switch (find_type(*option + 2, &option_types, FIND_TYPE_BASIC)) {
 	case OPT_port:
 	  if (opt_arg)
 	    options->port=atoi(opt_arg);
@@ -1338,8 +1345,8 @@ void mysql_read_default_options(struct s
 	    options->max_allowed_packet= atoi(opt_arg);
 	  break;
         case OPT_protocol:
-          if ((options->protocol= find_type(opt_arg,
-					    &sql_protocol_typelib,0)) <= 0)
+          if ((options->protocol= find_type(opt_arg, &sql_protocol_typelib,
+                                            FIND_TYPE_BASIC)) <= 0)
           {
             fprintf(stderr, "Unknown option to protocol: %s\n", opt_arg);
             exit(1);

=== modified file 'sql/sql_db.cc'
--- a/sql/sql_db.cc	2010-12-10 11:32:58 +0000
+++ b/sql/sql_db.cc	2011-02-10 13:57:46 +0000
@@ -1,18 +1,21 @@
-/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights
+   reserved.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 of the License.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; version 2 of
+   the License.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+   02110-1301  USA
+*/
 
 /* create and drop of databases */
 
@@ -1038,9 +1041,9 @@ static bool find_db_tables_and_rm_known_
     }
     if (!(extension= strrchr(file->name, '.')))
       extension= strend(file->name);
-    if (find_type(extension, &deletable_extentions,1+2) <= 0)
+    if (find_type(extension, &deletable_extentions, FIND_TYPE_NO_PREFIX) <= 0)
     {
-      if (find_type(extension, ha_known_exts(),1+2) <= 0)
+      if (find_type(extension, ha_known_exts(), FIND_TYPE_NO_PREFIX) <= 0)
 	*found_other_files= true;
       continue;
     }

=== modified file 'sql/sql_handler.cc'
--- a/sql/sql_handler.cc	2010-11-11 17:11:05 +0000
+++ b/sql/sql_handler.cc	2011-02-10 13:57:46 +0000
@@ -1,18 +1,21 @@
-/* Copyright (C) 2000-2004 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights
+   reserved.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 of the License.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; version 2 of
+   the License.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+   02110-1301  USA
+*/
 
 /* HANDLER ... commands - direct access to ISAM */
 
@@ -613,7 +616,8 @@ retry:
 
   if (keyname)
   {
-    if ((keyno=find_type(keyname, &table->s->keynames, 1+2)-1)<0)
+    if ((keyno= find_type(keyname, &table->s->keynames,
+                          FIND_TYPE_NO_PREFIX) - 1) < 0)
     {
       my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), keyname, tables->alias);
       goto err;

=== modified file 'sql/sql_help.cc'
--- a/sql/sql_help.cc	2010-10-20 19:02:59 +0000
+++ b/sql/sql_help.cc	2011-02-10 13:57:46 +0000
@@ -1,17 +1,21 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights
+   reserved.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 of the License.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; version 2 of
+   the License.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+   02110-1301  USA
+*/
 
 #include "sql_priv.h"
 #include "unireg.h"
@@ -284,10 +288,12 @@ int get_topics_for_keyword(THD *thd, TAB
   Field *rtopic_id, *rkey_id;
   DBUG_ENTER("get_topics_for_keyword");
 
-  if ((iindex_topic= find_type((char*) primary_key_name,
-			       &topics->s->keynames, 1+2)-1)<0 ||
-      (iindex_relations= find_type((char*) primary_key_name,
-				   &relations->s->keynames, 1+2)-1)<0)
+  if ((iindex_topic=
+       find_type(primary_key_name, &topics->s->keynames,
+                 FIND_TYPE_NO_PREFIX) - 1) < 0 ||
+      (iindex_relations=
+       find_type(primary_key_name, &relations->s->keynames,
+                 FIND_TYPE_NO_PREFIX) - 1) < 0)
   {
     my_message(ER_CORRUPT_HELP_DB, ER(ER_CORRUPT_HELP_DB), MYF(0));
     DBUG_RETURN(-1);

=== modified file 'sql/strfunc.cc'
--- a/sql/strfunc.cc	2010-03-31 14:05:33 +0000
+++ b/sql/strfunc.cc	2011-02-10 13:57:46 +0000
@@ -1,17 +1,21 @@
-/* Copyright (C) 2003 MySQL AB
+/* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights
+   reserved.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 of the License.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; version 2 of
+   the License.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+   02110-1301  USA
+*/
 
 /* Some useful string utility functions used by the MySQL server */
 
@@ -96,7 +100,7 @@ ulonglong find_set(TYPELIB *lib, const c
 
 /*
   Function to find a string in a TYPELIB
-  (Same format as mysys/typelib.c)
+  (similar to find_type() of mysys/typelib.c)
 
   SYNOPSIS
    find_type()

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2011-01-28 12:28:15 +0000
+++ b/sql/table.cc	2011-02-10 13:57:46 +0000
@@ -1444,8 +1444,8 @@ static int open_binary_frm(THD *thd, TAB
   /* Fix key->name and key_part->field */
   if (key_parts)
   {
-    uint primary_key=(uint) (find_type((char*) primary_key_name,
-				       &share->keynames, 3) - 1);
+    uint primary_key=(uint) (find_type(primary_key_name, &share->keynames,
+                                       FIND_TYPE_NO_PREFIX) - 1);
     longlong ha_option= handler_file->ha_table_flags();
     keyinfo= share->key_info;
     key_part= keyinfo->key_part;

=== modified file 'storage/myisam/myisamchk.c'
--- a/storage/myisam/myisamchk.c	2010-10-20 19:02:59 +0000
+++ b/storage/myisam/myisamchk.c	2011-02-10 13:57:46 +0000
@@ -1,17 +1,21 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights
+   reserved.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 of the License.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; version 2 of
+   the License.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+   02110-1301  USA
+*/
 
 /* Describe, check and repair of MyISAM tables */
 
@@ -673,7 +677,8 @@ get_one_option(int optid,
     int method;
     enum_mi_stats_method UNINIT_VAR(method_conv);
     myisam_stats_method_str= argument;
-    if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0)
+    if ((method= find_type(argument, &myisam_stats_method_typelib,
+                           FIND_TYPE_BASIC)) <= 0)
     {
       fprintf(stderr, "Invalid value of stats_method: %s.\n", argument);
       exit(1);

=== modified file 'storage/myisammrg/myrg_open.c'
--- a/storage/myisammrg/myrg_open.c	2010-11-16 09:45:07 +0000
+++ b/storage/myisammrg/myrg_open.c	2011-02-10 13:57:46 +0000
@@ -1,17 +1,21 @@
-/* Copyright (C) 2000-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights
+   reserved.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 of the License.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; version 2 of
+   the License.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+   02110-1301  USA
+*/
 
 /* open a MyISAM MERGE table */
 
@@ -77,7 +81,7 @@ MYRG_INFO *myrg_open(const char *name, i
     {
       if (!strncmp(buff+1,"INSERT_METHOD=",14))
       {			/* Lookup insert method */
-	int tmp=find_type(buff+15,&merge_insert_method,2);
+	int tmp= find_type(buff + 15, &merge_insert_method, FIND_TYPE_BASIC);
 	found_merge_insert_method = (uint) (tmp >= 0 ? tmp : 0);
       }
       continue;		/* Skip comments */
@@ -271,7 +275,7 @@ MYRG_INFO *myrg_parent_open(const char *
       {
         /* Compare buffer with global methods list: merge_insert_method. */
         insert_method= find_type(child_name_buff + 15,
-                                 &merge_insert_method, 2);
+                                 &merge_insert_method, FIND_TYPE_BASIC);
       }
       continue;
     }


Attachment: [text/bzr-bundle] bzr/guilhem.bichot@oracle.com-20110210135746-su4txsvi7c3ve3kg.bundle
Thread
[Resend] bzr commit into mysql-5.5 branch (guilhem.bichot:3315) Bug#59894Guilhem Bichot10 Feb
  • Re: [Resend] bzr commit into mysql-5.5 branch (guilhem.bichot:3315) Bug#59894Tor Didriksen10 Feb
    • Re: [Resend] bzr commit into mysql-5.5 branch (guilhem.bichot:3315)Bug#59894Guilhem Bichot10 Feb
  • Re: [Resend] bzr commit into mysql-5.5 branch (guilhem.bichot:3315)Bug#59894Gleb Shchepa10 Feb
    • Re: [Resend] bzr commit into mysql-5.5 branch (guilhem.bichot:3315)Bug#59894Guilhem Bichot10 Feb
      • Re: [Resend] bzr commit into mysql-5.5 branch (guilhem.bichot:3315)Bug#59894Gleb Shchepa10 Feb