List:Commits« Previous MessageNext Message »
From:Chad MILLER Date:April 4 2006 7:25pm
Subject:bk commit into 5.0 tree (cmiller:1.2112) BUG#18265
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of cmiller. When cmiller does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2112 06/04/04 15:24:53 cmiller@zippy.(none) +3 -0
  Bug#18265: mysql client: No longer right-justifies numeric columns
  
  Also fixes a new bug for which "NULL" wasn't printed (because the 
  data it represents has length zero).  (Discovered my Paul DuBois.)

  mysql-test/t/mysql.test
    1.8 06/04/04 15:24:50 cmiller@zippy.(none) +5 -0
    Added new test case.

  mysql-test/r/mysql.result
    1.7 06/04/04 15:24:50 cmiller@zippy.(none) +12 -3
    Updated old result and added new case.

  client/mysql.cc
    1.199 06/04/04 15:24:50 cmiller@zippy.(none) +50 -29
    Cleaned up the interactive-session table-printing function.
    
    - No longer rely on the length of the data to pad column boundries.
    - Be smarter about how we detect if the column is NULL.
    - Document how multibyte characters affect the output printing.
    - Use more descriptive variable names.
    
    More importantly, (re-)add these features that were crippled in an
    earlier change:
    - Print "NULL".
    - Right-justify numbers.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	cmiller
# Host:	zippy.(none)
# Root:	/home/cmiller/work/mysql/mysql-5.0__ready

--- 1.198/client/mysql.cc	2006-03-27 20:45:01 -05:00
+++ 1.199/client/mysql.cc	2006-04-04 15:24:50 -04:00
@@ -185,7 +185,7 @@
 void tee_fputs(const char *s, FILE *file);
 void tee_puts(const char *s, FILE *file);
 void tee_putc(int c, FILE *file);
-static void tee_print_sized_data(const char *data, unsigned int length, unsigned int width);
+static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
 /* The names of functions that actually do the manipulation. */
 static int get_options(int argc,char **argv);
 static int com_quit(String *str,char*),
@@ -2311,35 +2311,52 @@
   while ((cur= mysql_fetch_row(result)))
   {
     ulong *lengths= mysql_fetch_lengths(result);
-    (void) tee_fputs("|", PAGER);
+    (void) tee_fputs("| ", PAGER);
     mysql_field_seek(result, 0);
     for (uint off= 0; off < mysql_num_fields(result); off++)
     {
-      const char *str= cur[off] ? cur[off] : "NULL";
-      uint currlength;
-      uint maxlength;
-      uint numcells;
-
-      field= mysql_fetch_field(result);
-      maxlength= field->max_length;
-      currlength= (uint) lengths[off];
-      numcells= charset_info->cset->numcells(charset_info, 
-                                                    str, str + currlength);
-      if (maxlength > MAX_COLUMN_LENGTH)
+      const char *buffer;
+      uint data_length;
+      uint field_max_length;
+      bool right_justified;
+      uint visible_length;
+      uint extra_padding;
+
+      if (lengths[off] == 0) 
+      {
+        buffer= "NULL";
+        data_length= 4;
+      } 
+      else 
       {
-        tee_print_sized_data(str, currlength, maxlength);
-        tee_fputs(" |", PAGER);
+        buffer= cur[off];
+        data_length= (uint) lengths[off];
       }
+
+      field= mysql_fetch_field(result);
+      field_max_length= field->max_length;
+
+      /* 
+       How many text cells on the screen will this string span?  If it contains
+       multibyte characters, then the number of characters we occupy on screen
+       will be fewer than the number of bytes we occupy in memory.
+
+       We need to find how much screen real-estate we will occupy to know how 
+       many extra padding-characters we should send with the printing function.
+      */
+      visible_length= charset_info->cset->numcells(charset_info, buffer, buffer + data_length);
+      extra_padding= data_length - visible_length;
+
+      if (field_max_length > MAX_COLUMN_LENGTH)
+        tee_print_sized_data(buffer, data_length, MAX_COLUMN_LENGTH+extra_padding, FALSE);
       else
       {
-        if (num_flag[off] != 0)
-          tee_fprintf(PAGER, " %-*s|", maxlength + currlength - numcells, str);
+        if (num_flag[off] != 0) /* if it is numeric, we right-justify it */
+          tee_print_sized_data(buffer, data_length, field_max_length+extra_padding, TRUE);
         else 
-        {
-          tee_print_sized_data(str, currlength, maxlength);
-          tee_fputs(" |", PAGER);
-        }
+          tee_print_sized_data(buffer, data_length, field_max_length+extra_padding, FALSE);
       }
+      tee_fputs(" | ", PAGER);
     }
     (void) tee_fputs("\n", PAGER);
   }
@@ -2349,10 +2366,9 @@
 
 
 static void
-tee_print_sized_data(const char *data, unsigned int length, unsigned int width)
+tee_print_sized_data(const char *data, unsigned int data_length, unsigned int total_bytes_to_send, bool right_justified)
 {
   /* 
-    It is not a number, so print each character justified to the left.
     For '\0's print ASCII spaces instead, as '\0' is eaten by (at
     least my) console driver, and that messes up the pretty table
     grid.  (The \0 is also the reason we can't use fprintf() .) 
@@ -2360,9 +2376,14 @@
   unsigned int i;
   const char *p;
 
-  tee_putc(' ', PAGER);
+  total_bytes_to_send -= 1;  
+  /* Off by one, perhaps mistakenly accounting for a terminating NUL. */
 
-  for (i= 0, p= data; i < length; i+= 1, p+= 1)
+  if (right_justified) 
+    for (i= 0; i < (total_bytes_to_send - data_length); i++)
+      tee_putc((int)' ', PAGER);
+
+  for (i= 0, p= data; i < data_length; i+= 1, p+= 1)
   {
     if (*p == '\0')
       tee_putc((int)' ', PAGER);
@@ -2370,9 +2391,9 @@
       tee_putc((int)*p, PAGER);
   }
 
-  i+= 1; 
-  for (   ; i < width; i+= 1)
-    tee_putc((int)' ', PAGER);
+  if (! right_justified) 
+    for (i= 0; i < (total_bytes_to_send - data_length); i++)
+      tee_putc((int)' ', PAGER);
 }
 
 
@@ -3361,7 +3382,7 @@
     if (info_type == INFO_ERROR)
     {
       if (!opt_nobeep)
-	putchar('\007');		      	/* This should make a bell */
+        putchar('\a');		      	/* This should make a bell */
       vidattr(A_STANDOUT);
       if (error)
       {

--- 1.6/mysql-test/r/mysql.result	2006-03-03 16:26:34 -05:00
+++ 1.7/mysql-test/r/mysql.result	2006-04-04 15:24:50 -04:00
@@ -72,7 +72,16 @@
 +----------------------+------------+--------+
 | concat('>',col1,'<') | col2       | col3   |
 +----------------------+------------+--------+
-| >a   <               | b          | 123421 |
-| >a   <               | 0123456789 | 4      |
-| >abcd<               |            | 4      |
+| >a   <               | b          | 123421 | 
+| >a   <               | 0123456789 |      4 | 
+| >abcd<               | NULL       |      4 | 
 +----------------------+------------+--------+
++------+------+---------------------------+
+| i    | j    | k                         |
++------+------+---------------------------+
+|    1 | NULL | NULL                      | 
+| NULL | NULL | <-----------------------> | 
+| NULL | NULL | <-----                    | 
+| NULL | NULL |  [m~N[m~C[m~C             | 
+| NULL | NULL | [m~[~V[m~Z [m~Z[m~[~V[m~[ | 
++------+------+---------------------------+

--- 1.7/mysql-test/t/mysql.test	2006-03-03 16:26:34 -05:00
+++ 1.8/mysql-test/t/mysql.test	2006-04-04 15:24:50 -04:00
@@ -61,3 +61,8 @@
 # Bug#16859 -- NULLs in columns must not truncate data as if a C-language "string".
 #
 --exec $MYSQL -t test -e "create table t1 (col1 binary(4), col2 varchar(10), col3 int); insert into t1 values ('a', 'b', 123421),('a ', '0123456789', 4), ('abcd', '', 4); select concat('>',col1,'<'), col2, col3 from t1; drop table t1;" 2>&1
+
+#
+# Bug#18265 -- mysql client: No longer right-justifies numeric columns
+#
+--exec $MYSQL -t --default-character-set utf8 test -e "create table t1 (i int, j int, k char(25) charset utf8); insert into t1 (i) values (1); insert into t1 (k) values ('<----------------------->'); insert into t1 (k) values ('<-----'); insert into t1 (k) values (' [m~N[m~C[m~C'); insert into t1 (k) values ('[m~[~V[m~Z [m~Z[m~[~V[m~[~O '); select * from t1; DROP TABLE t1;"
Thread
bk commit into 5.0 tree (cmiller:1.2112) BUG#18265Chad MILLER4 Apr