List:Internals« Previous MessageNext Message »
From:monty Date:June 5 2005 2:19pm
Subject:bk commit into 5.0 tree (monty:1.1916)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of monty. When monty 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.1916 05/06/05 17:19:50 monty@stripped +17 -0
  merge

  sql/sp_head.cc
    1.142 05/06/05 17:19:46 monty@stripped +12 -13
    merge

  sql/sql_select.cc
    1.325 05/06/05 17:08:47 monty@stripped +0 -3
    Auto merged

  sql/sql_parse.cc
    1.446 05/06/05 17:08:46 monty@stripped +0 -0
    Auto merged

  sql/sql_insert.cc
    1.157 05/06/05 17:08:45 monty@stripped +0 -0
    Auto merged

  sql/sql_class.h
    1.234 05/06/05 17:08:45 monty@stripped +0 -0
    Auto merged

  sql/sql_bitmap.h
    1.9 05/06/05 17:08:44 monty@stripped +0 -0
    Auto merged

  sql/sql_base.cc
    1.251 05/06/05 17:08:44 monty@stripped +0 -0
    Auto merged

  sql/opt_range.cc
    1.167 05/06/05 17:08:44 monty@stripped +0 -0
    Auto merged

  sql/mysql_priv.h
    1.306 05/06/05 17:08:43 monty@stripped +0 -0
    Auto merged

  sql/item_sum.cc
    1.148 05/06/05 17:08:43 monty@stripped +0 -0
    Auto merged

  sql/item_subselect.cc
    1.106 05/06/05 17:08:42 monty@stripped +0 -0
    Auto merged

  sql/item_func.cc
    1.211 05/06/05 17:08:42 monty@stripped +0 -0
    Auto merged

  sql/item.h
    1.134 05/06/05 17:08:42 monty@stripped +0 -0
    Auto merged

  sql/item.cc
    1.132 05/06/05 17:08:41 monty@stripped +0 -0
    Auto merged

  sql/ha_ndbcluster.cc
    1.183 05/06/05 17:08:40 monty@stripped +0 -0
    Auto merged

  libmysql/libmysql.c
    1.217 05/06/05 17:08:39 monty@stripped +0 -0
    Auto merged

  client/mysql.cc
    1.172 05/06/05 17:08:36 monty@stripped +0 -0
    Auto merged

# 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:	monty
# Host:	narttu.mysql.com
# Root:	/home/my/mysql-5.0/RESYNC

--- 1.171/client/mysql.cc	2005-06-01 16:35:01 +03:00
+++ 1.172/client/mysql.cc	2005-06-05 17:08:36 +03:00
@@ -44,7 +44,7 @@
 #include <locale.h>
 #endif
 
-const char *VER= "14.10";
+const char *VER= "14.11";
 
 /* Don't try to make a nice table if the data is too big */
 #define MAX_COLUMN_LENGTH	     1024
@@ -1918,7 +1918,7 @@
       time_buff[0]=0;
     if (result)
     {
-      if (!mysql_num_rows(result) && ! quick)
+      if (!mysql_num_rows(result) && ! quick && !info_flag)
       {
 	strmov(buff, "Empty set");
       }
@@ -2050,18 +2050,93 @@
   return result;
 }
 
+static char *fieldtype2str(enum enum_field_types type) {
+  switch(type) {
+    case FIELD_TYPE_BIT:         return "BIT";
+    case FIELD_TYPE_BLOB:        return "BLOB";
+    case FIELD_TYPE_DATE:        return "DATE";
+    case FIELD_TYPE_DATETIME:    return "DATETIME";
+    case FIELD_TYPE_NEWDECIMAL:  return "NEWDECIMAL";
+    case FIELD_TYPE_DECIMAL:     return "DECIMAL";
+    case FIELD_TYPE_DOUBLE:      return "DOUBLE";
+    case FIELD_TYPE_ENUM:        return "ENUM";
+    case FIELD_TYPE_FLOAT:       return "FLOAT";
+    case FIELD_TYPE_GEOMETRY:    return "GEOMETRY";
+    case FIELD_TYPE_INT24:       return "INT24";
+    case FIELD_TYPE_LONG:        return "LONG";
+    case FIELD_TYPE_LONGLONG:    return "LONGLONG";
+    case FIELD_TYPE_LONG_BLOB:   return "LONG_BLOB";
+    case FIELD_TYPE_MEDIUM_BLOB: return "MEDIUM_BLOB";
+    case FIELD_TYPE_NEWDATE:     return "NEWDATE";
+    case FIELD_TYPE_NULL:        return "NULL";
+    case FIELD_TYPE_SET:         return "SET";
+    case FIELD_TYPE_SHORT:       return "SHORT";
+    case FIELD_TYPE_STRING:      return "STRING";
+    case FIELD_TYPE_TIME:        return "TIME";
+    case FIELD_TYPE_TIMESTAMP:   return "TIMESTAMP";
+    case FIELD_TYPE_TINY:        return "TINY";
+    case FIELD_TYPE_TINY_BLOB:   return "TINY_BLOB";
+    case FIELD_TYPE_VAR_STRING:  return "VAR_STRING";
+    case FIELD_TYPE_YEAR:        return "YEAR";
+    default:                     return "?-unknown-?";
+  }
+}
+
+static char *fieldflags2str(uint f) {
+  static char buf[1024];
+  char *s=buf;
+  *s=0;
+#define ff2s_check_flag(X) \
+                if (f & X ## _FLAG) { s=strmov(s, # X " "); f &= ~ X ## _FLAG; }
+  ff2s_check_flag(NOT_NULL);
+  ff2s_check_flag(PRI_KEY);
+  ff2s_check_flag(UNIQUE_KEY);
+  ff2s_check_flag(MULTIPLE_KEY);
+  ff2s_check_flag(BLOB);
+  ff2s_check_flag(UNSIGNED);
+  ff2s_check_flag(ZEROFILL);
+  ff2s_check_flag(BINARY);
+  ff2s_check_flag(ENUM);
+  ff2s_check_flag(AUTO_INCREMENT);
+  ff2s_check_flag(TIMESTAMP);
+  ff2s_check_flag(SET);
+  ff2s_check_flag(NO_DEFAULT_VALUE);
+  ff2s_check_flag(NUM);
+  ff2s_check_flag(PART_KEY);
+  ff2s_check_flag(GROUP);
+  ff2s_check_flag(UNIQUE);
+  ff2s_check_flag(BINCMP);
+#undef ff2s_check_flag
+  if (f)
+    sprintf(s, " unknows=0x%04x", f);
+  return buf;
+}
+
 static void
 print_field_types(MYSQL_RES *result)
 {
-  MYSQL_FIELD	*field;  
+  MYSQL_FIELD   *field;
+  uint i=0;
+
   while ((field = mysql_fetch_field(result)))
   {
-    tee_fprintf(PAGER,"Catalog:    '%s'\nDatabase:   '%s'\nTable:      '%s'\nName:       '%s'\nType:       %d\nLength:     %ld\nMax length: %ld\nIs_null:    %d\nFlags:      %u\nDecimals:   %u\n\n",
-		field->catalog, field->db, field->table, field->name,
-		(int) field->type,
-		field->length, field->max_length,
-		!IS_NOT_NULL(field->flags),
-		field->flags, field->decimals);
+    tee_fprintf(PAGER, "Field %3u:  `%s`\n"
+                       "Catalog:    `%s`\n"
+                       "Database:   `%s`\n"
+                       "Table:      `%s`\n"
+                       "Org_table:  `%s`\n"
+                       "Type:       %s\n"
+                       "Collation:  %s (%u)\n"
+                       "Length:     %lu\n"
+                       "Max_length: %lu\n"
+                       "Decimals:   %u\n"
+                       "Flags:      %s\n\n",
+                ++i,
+                field->name, field->catalog, field->db, field->table,
+                field->org_table, fieldtype2str(field->type),
+                get_charset_name(field->charsetnr), field->charsetnr,
+                field->length, field->max_length, field->decimals,
+                fieldflags2str(field->flags));
   }
   tee_puts("", PAGER);
 }
@@ -2079,6 +2154,8 @@
   if (info_flag)
   {
     print_field_types(result);
+    if (!mysql_num_rows(result))
+      return;
     mysql_field_seek(result,0);
   }
   separator.copy("+",1,charset_info);

--- 1.216/libmysql/libmysql.c	2005-06-04 11:37:04 +03:00
+++ 1.217/libmysql/libmysql.c	2005-06-05 17:08:39 +03:00
@@ -1738,7 +1738,7 @@
 
 /* Default number of rows fetched per one COM_FETCH command. */
 
-#define DEFAULT_PREFETCH_ROWS 1UL
+#define DEFAULT_PREFETCH_ROWS (ulong) 1
 
 /*
   These functions are called by function pointer MYSQL_STMT::read_row_func.

--- 1.131/sql/item.cc	2005-06-02 23:02:41 +03:00
+++ 1.132/sql/item.cc	2005-06-05 17:08:41 +03:00
@@ -2248,9 +2248,8 @@
       SELECT_LEX_UNIT::item set only for subqueries, so test of it presence
       can be barrier to stop before derived table SELECT or very outer SELECT
     */
-    for(;
-        cursel->master_unit()->item;
-        cursel= cursel->outer_select())
+    for (; cursel->master_unit()->item;
+         cursel= cursel->outer_select())
     {
       Item_subselect *subselect_item= cursel->master_unit()->item;
       subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
@@ -2530,9 +2529,8 @@
     resolving)
   */
   SELECT_LEX *previous_select= current_sel;
-  for(;
-      previous_select->outer_select() != last_select;
-      previous_select= previous_select->outer_select())
+  for (; previous_select->outer_select() != last_select;
+       previous_select= previous_select->outer_select())
   {
     Item_subselect *prev_subselect_item=
       previous_select->master_unit()->item;

--- 1.133/sql/item.h	2005-06-03 13:56:45 +03:00
+++ 1.134/sql/item.h	2005-06-05 17:08:42 +03:00
@@ -284,7 +284,9 @@
   Item(THD *thd, Item *item);
   virtual ~Item()
   {
+#ifdef EXTRA_DEBUG
     name=0;
+#endif
   }		/*lint -e1509 */
   void set_name(const char *str,uint length, CHARSET_INFO *cs);
   void rename(char *new_name);

--- 1.210/sql/item_func.cc	2005-06-03 14:42:57 +03:00
+++ 1.211/sql/item_func.cc	2005-06-05 17:08:42 +03:00
@@ -213,15 +213,16 @@
 {
   allowed_arg_cols= 1;
   arg_count=list.elements;
-  if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
+  args= tmp_arg;                                // If 2 arguments
+  if (arg_count <= 2 || (args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
   {
-    uint i=0;
     List_iterator_fast<Item> li(list);
     Item *item;
+    Item **save_args= args;
 
     while ((item=li++))
     {
-      args[i++]= item;
+      *(save_args++)= item;
       with_sum_func|=item->with_sum_func;
     }
   }

--- 1.147/sql/item_sum.cc	2005-06-02 08:49:57 +03:00
+++ 1.148/sql/item_sum.cc	2005-06-05 17:08:43 +03:00
@@ -242,8 +242,12 @@
   case REAL_RESULT:
     sum= item->sum;
     break;
-  case STRING_RESULT: // This can happen with ROLLUP. Note that the value is already
-    break;            // copied at function call.
+  case STRING_RESULT:
+    /*
+      This can happen with ROLLUP. Note that the value is already
+      copied at function call.
+    */
+    break;
   case ROW_RESULT:
   default:
     DBUG_ASSERT(0);

--- 1.305/sql/mysql_priv.h	2005-06-01 11:52:58 +03:00
+++ 1.306/sql/mysql_priv.h	2005-06-05 17:08:43 +03:00
@@ -94,7 +94,7 @@
 #define MAX_FIELDS_BEFORE_HASH	32
 #define USER_VARS_HASH_SIZE     16
 #define STACK_MIN_SIZE		8192	// Abort if less stack during eval.
-#define STACK_BUFF_ALLOC	64	// For stack overrun checks
+#define STACK_BUFF_ALLOC	256	// For stack overrun checks
 #ifndef MYSQLD_NET_RETRY_COUNT
 #define MYSQLD_NET_RETRY_COUNT  10	// Abort read after this many int.
 #endif

--- 1.166/sql/opt_range.cc	2005-06-01 16:35:03 +03:00
+++ 1.167/sql/opt_range.cc	2005-06-05 17:08:44 +03:00
@@ -36,6 +36,8 @@
      QUICK_RANGEs are also created in this step.
 */
 
+#include <my_global.h>
+
 #ifdef USE_PRAGMA_IMPLEMENTATION
 #pragma implementation				// gcc: Class implementation
 #endif

--- 1.250/sql/sql_base.cc	2005-06-02 16:30:37 +03:00
+++ 1.251/sql/sql_base.cc	2005-06-05 17:08:44 +03:00
@@ -753,7 +753,7 @@
   t_name= table->table_name;
 
   DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name));
-  for(;;)
+  for (;;)
   {
     if (!(res= find_table_in_global_list(table_list, d_name, t_name)) ||
         (!res->table || res->table != table->table) &&

--- 1.233/sql/sql_class.h	2005-05-30 20:48:36 +03:00
+++ 1.234/sql/sql_class.h	2005-06-05 17:08:45 +03:00
@@ -695,7 +695,8 @@
   virtual Type type() const;
   virtual ~Item_arena() {};
 
-  inline bool is_stmt_prepare() const { return (int)state < (int)PREPARED; }
+  inline bool is_stmt_prepare_or_first_sp_execute() const
+  { return (int)state < (int)PREPARED; }
   inline bool is_first_stmt_execute() const { return state == PREPARED; }
   inline bool is_stmt_execute() const
   { return state == PREPARED || state == EXECUTED; }

--- 1.156/sql/sql_insert.cc	2005-06-02 07:15:15 +03:00
+++ 1.157/sql/sql_insert.cc	2005-06-05 17:08:45 +03:00
@@ -128,7 +128,7 @@
       /* it is join view => we need to find table for update */
       List_iterator_fast<Item> it(fields);
       Item *item;
-      TABLE_LIST *tbl= 0;
+      TABLE_LIST *tbl= 0;            // reset for call to check_single_table()
       table_map map= 0;
 
       while ((item= it++))
@@ -1012,6 +1012,7 @@
 
 err:
   info->last_errno= error;
+  thd->lex->current_select->no_error= 0;        // Give error
   table->file->print_error(error,MYF(0));
 
 before_trg_err:

--- 1.445/sql/sql_parse.cc	2005-06-02 23:02:41 +03:00
+++ 1.446/sql/sql_parse.cc	2005-06-05 17:08:46 +03:00
@@ -4537,7 +4537,8 @@
         send_ok(thd);
       break;
     }
-    if (thd->transaction.xa_state == XA_IDLE && thd->lex->xa_opt == XA_ONE_PHASE)
+    if (thd->transaction.xa_state == XA_IDLE &&
+        thd->lex->xa_opt == XA_ONE_PHASE)
     {
       int r;
       if ((r= ha_commit(thd)))
@@ -4545,8 +4546,8 @@
       else
         send_ok(thd);
     }
-    else
-    if (thd->transaction.xa_state == XA_PREPARED && thd->lex->xa_opt == XA_NONE)
+    else if (thd->transaction.xa_state == XA_PREPARED &&
+             thd->lex->xa_opt == XA_NONE)
     {
       if (wait_if_global_read_lock(thd, 0, 0))
       {

--- 1.324/sql/sql_select.cc	2005-06-02 21:55:30 +03:00
+++ 1.325/sql/sql_select.cc	2005-06-05 17:08:47 +03:00
@@ -957,32 +957,35 @@
 #endif
 
   DBUG_EXECUTE("info",TEST_join(this););
-  /*
-    Because filesort always does a full table scan or a quick range scan
-    we must add the removed reference to the select for the table.
-    We only need to do this when we have a simple_order or simple_group
-    as in other cases the join is done before the sort.
-  */
-  if (const_tables != tables &&
-      (order || group_list) &&
-      join_tab[const_tables].type != JT_ALL &&
-      join_tab[const_tables].type != JT_FT &&
-      join_tab[const_tables].type != JT_REF_OR_NULL &&
-      (order && simple_order || group_list && simple_group))
-  {
-    if (add_ref_to_table_cond(thd,&join_tab[const_tables]))
-      DBUG_RETURN(1);
-  }
 
-  if (!(select_options & SELECT_BIG_RESULT) &&
-      ((group_list && const_tables != tables &&
-	(!simple_group ||
-	 !test_if_skip_sort_order(&join_tab[const_tables], group_list,
-				  unit->select_limit_cnt, 0))) ||
-       select_distinct) &&
-      tmp_table_param.quick_group && !procedure)
+  if (const_tables != tables)
   {
-    need_tmp=1; simple_order=simple_group=0;	// Force tmp table without sort
+    /*
+      Because filesort always does a full table scan or a quick range scan
+      we must add the removed reference to the select for the table.
+      We only need to do this when we have a simple_order or simple_group
+      as in other cases the join is done before the sort.
+    */
+    if ((order || group_list) &&
+        join_tab[const_tables].type != JT_ALL &&
+        join_tab[const_tables].type != JT_FT &&
+        join_tab[const_tables].type != JT_REF_OR_NULL &&
+        (order && simple_order || group_list && simple_group))
+    {
+      if (add_ref_to_table_cond(thd,&join_tab[const_tables]))
+        DBUG_RETURN(1);
+    }
+    
+    if (!(select_options & SELECT_BIG_RESULT) &&
+        ((group_list &&
+          (!simple_group ||
+           !test_if_skip_sort_order(&join_tab[const_tables], group_list,
+                                    unit->select_limit_cnt, 0))) ||
+         select_distinct) &&
+        tmp_table_param.quick_group && !procedure)
+    {
+      need_tmp=1; simple_order=simple_group=0;	// Force tmp table without sort
+    }
   }
 
   tmp_having= having;
@@ -5381,6 +5384,8 @@
       JOIN_TAB *first_inner_tab= tab->first_inner; 
       table_map current_map= tab->table->map;
       bool use_quick_range=0;
+      COND *tmp;
+
       /*
 	Following force including random expression in last table condition.
 	It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
@@ -5402,7 +5407,7 @@
 	join->best_positions[i].records_read= rows2double(tab->quick->records);
       }
 
-      COND *tmp= NULL;
+      tmp= NULL;
       if (cond)
         tmp= make_cond_for_table(cond,used_tables,current_map);
       if (cond && !tmp && tab->quick)
@@ -13610,7 +13615,7 @@
   (*table)->print(thd, str);
 
   TABLE_LIST **end= table + tables->elements;
-  for(TABLE_LIST **tbl= table + 1; tbl < end; tbl++)
+  for (TABLE_LIST **tbl= table + 1; tbl < end; tbl++)
   {
     TABLE_LIST *curr= *tbl;
     if (curr->outer_join)

--- 1.105/sql/item_subselect.cc	2005-06-01 16:35:02 +03:00
+++ 1.106/sql/item_subselect.cc	2005-06-05 17:08:42 +03:00
@@ -22,6 +22,8 @@
      (sql_select.h/sql_select.cc)
 */
 
+#include <my_global.h>
+
 #ifdef USE_PRAGMA_IMPLEMENTATION
 #pragma implementation				// gcc: Class implementation
 #endif
@@ -360,7 +362,7 @@
         because we do not rollback this changes
         TODO: make rollback for it, or special name resolving mode in 5.0.
       */
-      !arena->is_stmt_prepare()
+      !arena->is_stmt_prepare_or_first_sp_execute()
       )
   {
 
@@ -384,9 +386,6 @@
     return RES_REDUCE;
   }
   return RES_OK;
-
-err:
-  return RES_ERROR;
 }
 
 

--- 1.182/sql/ha_ndbcluster.cc	2005-06-02 18:06:47 +03:00
+++ 1.183/sql/ha_ndbcluster.cc	2005-06-05 17:08:40 +03:00
@@ -5592,8 +5592,8 @@
   const NDBINDEX *idx= (NDBINDEX *) m_index[active_index].index; 
   const NdbOperation* lastOp= m_active_trans->getLastDefinedOperation();
   NdbIndexScanOperation* scanOp= 0;
-  for(; multi_range_curr<multi_range_end && curr+reclength <= end_of_buffer; 
-      multi_range_curr++)
+  for (; multi_range_curr<multi_range_end && curr+reclength <= end_of_buffer; 
+       multi_range_curr++)
   {
     switch(index_type){
     case PRIMARY_KEY_INDEX:
@@ -5730,7 +5730,7 @@
   int range_no;
   ulong reclength= table->s->reclength;
   const NdbOperation* op= m_current_multi_operation;
-  for(;multi_range_curr < m_multi_range_defined; multi_range_curr++)
+  for (;multi_range_curr < m_multi_range_defined; multi_range_curr++)
   {
     if (multi_range_curr->range_flag & UNIQUE_RANGE)
     {

--- 1.141/sql/sp_head.cc	2005-06-01 13:17:38 +03:00
+++ 1.142/sql/sp_head.cc	2005-06-05 17:19:46 +03:00
@@ -1904,32 +1904,32 @@
   else
   {
     sp_lex_keeper *lex_keeper= c->pre_open(thd);
-
-    if (!lex_keeper)
+    if (!lex_keeper)                            // cursor already open or OOM
     {
       res= -1;
       *nextp= m_ip+1;
     }
     else
-      res= lex_keeper->reset_lex_and_exec_core(thd, nextp, FALSE, this);
-
-    /*
-      Work around the fact that errors in selects are not returned properly
-      (but instead converted into a warning), so if a condition handler
-      caught, we have lost the result code.
-     */
-    if (!res)
     {
-      uint dummy1, dummy2;
+      res= lex_keeper->reset_lex_and_exec_core(thd, nextp, FALSE, this);
+      /*
+        Work around the fact that errors in selects are not returned properly
+        (but instead converted into a warning), so if a condition handler
+        caught, we have lost the result code.
+       */
+      if (!res)
+      {
+        uint dummy1, dummy2;
 
-      if (thd->spcont->found_handler(&dummy1, &dummy2))
-	res= -1;
+        if (thd->spcont->found_handler(&dummy1, &dummy2))
+  	  res= -1;
+      }
+      c->post_open(thd, res ? FALSE : TRUE);
     }
-    c->post_open(thd, (lex_keeper && !res ? TRUE : FALSE));
   }
-
   DBUG_RETURN(res);
 }
+
 
 int
 sp_instr_copen::exec_core(THD *thd, uint *nextp)

--- 1.8/sql/sql_bitmap.h	2005-06-01 16:35:04 +03:00
+++ 1.9/sql/sql_bitmap.h	2005-06-05 17:08:44 +03:00
@@ -28,7 +28,7 @@
   uchar buffer[(default_width+7)/8];
 public:
   Bitmap() { init(); }
-  Bitmap(Bitmap& from) { *this=from; }
+  Bitmap(const Bitmap& from) { *this=from; }
   explicit Bitmap(uint prefix_to_set) { init(prefix_to_set); }
   void init() { bitmap_init(&map, buffer, default_width, 0); }
   void init(uint prefix_to_set) { init(); set_prefix(prefix_to_set); }
@@ -61,18 +61,17 @@
   my_bool operator==(const Bitmap& map2) const { return bitmap_cmp(&map, &map2.map); }
   char *print(char *buf) const
   {
-    char *s=buf; int i;
-    for (i=sizeof(buffer)-1; i>=0 ; i--)
+    char *s=buf;
+    const uchar *e=buffer, *b=e+sizeof(buffer)-1;
+    while (!*b && b>e)
+      b--;
+    if ((*s=_dig_vec_upper[*b >> 4]) != '0')
+        s++;
+    *s++=_dig_vec_upper[*b & 15];
+    while (--b>=e)
     {
-      if ((*s=_dig_vec_upper[buffer[i] >> 4]) != '0')
-        break;
-      if ((*s=_dig_vec_upper[buffer[i] & 15]) != '0')
-        break;
-    }
-    for (s++, i-- ; i>=0 ; i--)
-    {
-      *s++=_dig_vec_upper[buffer[i] >> 4];
-      *s++=_dig_vec_upper[buffer[i] & 15];
+      *s++=_dig_vec_upper[*b >> 4];
+      *s++=_dig_vec_upper[*b & 15];
     }
     *s=0;
     return buf;
Thread
bk commit into 5.0 tree (monty:1.1916)monty5 Jun