List:Commits« Previous MessageNext Message »
From:Libing Song Date:January 28 2011 3:32am
Subject:bzr commit into mysql-trunk branch (anders.song:3516) Bug#33048
View as plain text  
#At file:///home/anders/Work/bzrwork/wt1/mysql-trunk/ based on revid:anders.song@stripped

 3516 Libing Song	2011-01-28
      BUG#33048 Post patch
      To disable mysql client commands in binary mode, except
      'delimiter' and '\C'.

    modified:
      client/mysql.cc
=== modified file 'client/mysql.cc'
--- a/client/mysql.cc	2011-01-26 07:13:45 +0000
+++ b/client/mysql.cc	2011-01-28 03:32:51 +0000
@@ -1045,7 +1045,8 @@ static void initialize_readline (char *n
 static void fix_history(String *final_command);
 #endif
 
-static COMMANDS *find_command(char *name,char cmd_name);
+static COMMANDS *find_command(char *name);
+static COMMANDS *find_command(char cmd_name);
 static bool add_line(String &buffer, char *line, ulong line_length,
                      char *in_string, bool *ml_comment, bool truncated);
 static void remove_cntrl(String &buffer);
@@ -1065,6 +1066,31 @@ extern "C" sig_handler handle_sigint(int
 static sig_handler window_resize(int sig);
 #endif
 
+const char DELIMITER_NAME[]= "delimiter";
+const uint DELIMITER_NAME_LEN= sizeof(DELIMITER_NAME) - 1;
+inline bool is_delimiter_command(char *name, ulong len)
+{
+  DBUG_PRINT("slb-", ("len: %d", DELIMITER_NAME_LEN));
+  return  (len == DELIMITER_NAME_LEN &&
+           !my_strnncoll(charset_info, (uchar*)name, DELIMITER_NAME_LEN,
+                         (uchar *)DELIMITER_NAME, DELIMITER_NAME_LEN));
+}
+
+inline int get_command_index(char cmd_char)
+{
+  /*
+    All commands are in the first part of commands array and have a function
+    to implemente it.
+  */
+  for (uint i=0; *commands[i].func; i++)
+    if (commands[i].cmd_char == cmd_char)
+      return i;
+  return -1;
+}
+
+static int delimiter_index= -1;
+static int charset_index= -1;
+static bool real_binary_mode= FALSE;
 
 int main(int argc,char *argv[])
 {
@@ -1073,7 +1099,9 @@ int main(int argc,char *argv[])
   MY_INIT(argv[0]);
   DBUG_ENTER("main");
   DBUG_PROCESS(argv[0]);
-  
+
+  charset_index= get_command_index('C');
+  delimiter_index= get_command_index('d');
   delimiter_str= delimiter;
   default_prompt = my_strdup(getenv("MYSQL_PS1") ? 
 			     getenv("MYSQL_PS1") : 
@@ -1852,18 +1880,18 @@ static int read_and_execute(bool interac
   bool truncated= 0;
   ulong line_length= 0;
   status.exit_status=1;
-  
+  real_binary_mode= (!interactive && opt_binary_mode);
   for (;;)
   {
     if (!interactive)
     {
-      line=batch_readline(status.line_buff, &truncated, opt_binary_mode);
+      line=batch_readline(status.line_buff, &truncated, real_binary_mode);
       line_length= status.line_buff->read_length;
       /*
         ASCII 0x00 is not allowed appearing in queries if it is not in binary
         mode.
       */
-      if (!opt_binary_mode && line && strlen(line) != line_length)
+      if (!real_binary_mode && line && strlen(line) != line_length)
       {
         status.exit_status= 1;
         String msg;
@@ -1952,7 +1980,7 @@ static int read_and_execute(bool interac
       (We want to allow help, print and clear anywhere at line start
     */
     if ((named_cmds || glob_buffer.is_empty())
-	&& !ml_comment && !in_string && (com=find_command(line,0)))
+	&& !ml_comment && !in_string && (com=find_command(line)))
     {
       if ((*com->func)(&glob_buffer,line) > 0)
 	break;
@@ -1985,65 +2013,96 @@ static int read_and_execute(bool interac
   buffer.free();
   tmpbuf.free();
 #endif
-
+  real_binary_mode= FALSE;
   return status.exit_status;
 }
 
+static COMMANDS *find_command(char cmd_char)
+{
+  DBUG_ENTER("find_command");
+  DBUG_PRINT("enter", ("cmd_char: %d", cmd_char));
+
+  int index= -1;
+  if (real_binary_mode)
+  {
+    if (cmd_char == 'C')
+      index= charset_index;
+  }
+  else
+    index= get_command_index(cmd_char);
+
+  if (index >= 0)
+  {
+    DBUG_PRINT("exit",("found command: %s", commands[index].name));
+    DBUG_RETURN(&commands[index]);
+  }
+  else
+    DBUG_RETURN((COMMANDS *) 0);
+}
 
-static COMMANDS *find_command(char *name,char cmd_char)
+static COMMANDS *find_command(char *name)
 {
   uint len;
   char *end;
   DBUG_ENTER("find_command");
-  DBUG_PRINT("enter",("name: '%s'  char: %d", name ? name : "NULL", cmd_char));
 
-  if (!name)
+  DBUG_ASSERT(name != NULL);
+  DBUG_PRINT("enter", ("name: '%s'", name));
+
+  while (my_isspace(charset_info,*name))
+    name++;
+  /*
+    If there is an \\g in the row or if the row has a delimiter but
+    this is not a delimiter command, let add_line() take care of
+    parsing the row and calling find_command()
+  */
+  if ((!real_binary_mode && strstr(name, "\\g")) ||
+      (strstr(name, delimiter) &&
+       !is_delimiter_command(name, DELIMITER_NAME_LEN)))
+      DBUG_RETURN((COMMANDS *) 0);
+
+  if ((end=strcont(name," \t")))
+  {
+    len=(uint) (end - name);
+    while (my_isspace(charset_info,*end))
+      end++;
+    if (!*end)
+      end=0;					// no arguments to function
+  }
+  else
+    len=(uint) strlen(name);
+
+  int index= -1;
+  if (real_binary_mode)
   {
-    len=0;
-    end=0;
+    if (is_delimiter_command(name, len))
+      index= delimiter_index;
   }
   else
   {
-    while (my_isspace(charset_info,*name))
-      name++;
     /*
-      If there is an \\g in the row or if the row has a delimiter but
-      this is not a delimiter command, let add_line() take care of
-      parsing the row and calling find_command()
+      All commands are in the first part of commands array and have a function
+      to implemente it.
     */
-    if (strstr(name, "\\g") || (strstr(name, delimiter) &&
-                                !(strlen(name) >= 9 &&
-                                  !my_strnncoll(&my_charset_latin1,
-                                                (uchar*) name, 9,
-                                                (const uchar*) "delimiter",
-                                                9))))
-      DBUG_RETURN((COMMANDS *) 0);
-    if ((end=strcont(name," \t")))
+    for (uint i= 0; commands[i].func; i++)
     {
-      len=(uint) (end - name);
-      while (my_isspace(charset_info,*end))
-	end++;
-      if (!*end)
-	end=0;					// no arguments to function
+      if (commands[i].name[len] == '\0' &&
+          !my_strnncoll(&my_charset_latin1, (uchar*)name, len,
+                        (uchar*)commands[i].name,len) &&
+          (!end || commands[i].takes_params))
+      {
+        index= i;
+        break;
+      }
     }
-    else
-      len=(uint) strlen(name);
   }
 
-  for (uint i= 0; commands[i].name; i++)
+  if (index >= 0)
   {
-    if (commands[i].func &&
-	((name &&
-	  !my_strnncoll(&my_charset_latin1, (uchar*)name, len,
-				     (uchar*)commands[i].name,len) &&
-	  !commands[i].name[len] &&
-	  (!end || (end && commands[i].takes_params))) ||
-	 (!name && commands[i].cmd_char == cmd_char)))
-    {
-      DBUG_PRINT("exit",("found command: %s", commands[i].name));
-      DBUG_RETURN(&commands[i]);
-    }
+    DBUG_PRINT("exit",("found command: %s", commands[index].name));
+    DBUG_RETURN(&commands[index]);
   }
+
   DBUG_RETURN((COMMANDS *) 0);
 }
 
@@ -2108,7 +2167,7 @@ static bool add_line(String &buffer, cha
 	*out++= (char) inchar;
 	continue;
       }
-      if ((com=find_command(NullS,(char) inchar)))
+      if ((com=find_command((char) inchar)))
       {
         // Flush previously accepted characters
         if (out != line)
@@ -2184,7 +2243,7 @@ static bool add_line(String &buffer, cha
 
       pos--;
 
-      if ((com= find_command(buffer.c_ptr(), 0)))
+      if ((com= find_command(buffer.c_ptr())))
       {
           
         if ((*com->func)(&buffer, buffer.c_ptr()) > 0)
@@ -2299,9 +2358,7 @@ static bool add_line(String &buffer, cha
     uint length=(uint) (out-line);
 
     if (!truncated &&
-        (length < 9 || 
-         my_strnncoll (charset_info, 
-                       (uchar *)line, 9, (const uchar *) "delimiter", 9)))
+        (length < 9 || !is_delimiter_command(line, DELIMITER_NAME_LEN)))
     {
       /* 
         Don't add a new line in case there's a DELIMITER command to be 


Attachment: [text/bzr-bundle] bzr/anders.song@greatopensource.com-20110128033251-eg3xq9h669veta8m.bundle
Thread
bzr commit into mysql-trunk branch (anders.song:3516) Bug#33048Libing Song28 Jan