MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:gluh Date:February 28 2007 2:48pm
Subject:bk commit into 5.2 tree (gluh:1.2454)
View as plain text  
Below is the list of changes that have just been committed into a local
5.2 repository of gluh. When gluh 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@stripped, 2007-02-28 18:48:13+04:00, gluh@eagle.(none) +27 -0
  Merge mysql.com:/home/gluh/MySQL/Merge/5.1-opt
  into  mysql.com:/home/gluh/MySQL/Merge/5.2-opt
  MERGE: 1.2451.1.14

  configure.in@stripped, 2007-02-28 18:27:03+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.330.1.109

  mysql-test/mysql-test-run.pl@stripped, 2007-02-28 18:27:03+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.122.1.151

  mysql-test/r/innodb.result@stripped, 2007-02-28 18:27:03+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.165.4.11

  sql/event_scheduler.cc@stripped, 2007-02-28 18:27:03+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.27.1.5

  sql/ha_ndbcluster_binlog.cc@stripped, 2007-02-28 18:27:03+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.90.1.14

  sql/handler.cc@stripped, 2007-02-28 18:27:03+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.215.2.82

  sql/item.cc@stripped, 2007-02-28 18:27:04+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.167.1.79

  sql/item.h@stripped, 2007-02-28 18:27:04+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.190.1.37

  sql/item_func.cc@stripped, 2007-02-28 18:27:04+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.355.1.2

  sql/lock.cc@stripped, 2007-02-28 18:27:04+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.97.1.6

  sql/log_event.cc@stripped, 2007-02-28 18:27:04+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.266.1.1

  sql/repl_failsafe.cc@stripped, 2007-02-28 18:27:04+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.66.1.8

  sql/slave.cc@stripped, 2007-02-28 18:27:04+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.300.1.8

  sql/sql_base.cc@stripped, 2007-02-28 18:27:04+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.374.1.4

  sql/sql_class.cc@stripped, 2007-02-28 18:27:04+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.312.1.3

  sql/sql_class.h@stripped, 2007-02-28 18:27:04+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.339.1.1

  sql/sql_delete.cc@stripped, 2007-02-28 18:27:05+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.204.1.5

  sql/sql_insert.cc@stripped, 2007-02-28 18:27:05+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.246.1.4

  sql/sql_parse.cc@stripped, 2007-02-28 18:48:11+04:00, gluh@eagle.(none) +0 -0
    SCCS merged
    MERGE: 1.626.1.3

  sql/sql_partition.cc@stripped, 2007-02-28 18:27:05+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.96.1.4

  sql/sql_repl.cc@stripped, 2007-02-28 18:27:05+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.155.1.6

  sql/sql_select.cc@stripped, 2007-02-28 18:27:05+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.492.1.5

  sql/sql_table.cc@stripped, 2007-02-28 18:27:05+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.388.1.5

  sql/sql_update.cc@stripped, 2007-02-28 18:27:05+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.215.1.12

  sql/sql_view.cc@stripped, 2007-02-28 18:27:06+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.116.1.7

  sql/sql_yacc.yy@stripped, 2007-02-28 18:27:06+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.458.2.82

  storage/innobase/handler/ha_innodb.cc@stripped, 2007-02-28 18:27:06+04:00, gluh@eagle.(none) +0 -0
    Auto merged
    MERGE: 1.257.2.65

# 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:	gluh
# Host:	eagle.(none)
# Root:	/home/gluh/MySQL/Merge/5.2-opt/RESYNC

--- 1.356/configure.in	2007-02-23 03:01:53 +04:00
+++ 1.357/configure.in	2007-02-28 18:27:03 +04:00
@@ -715,7 +715,7 @@ AC_CHECK_HEADERS(fcntl.h float.h floatin
  sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
  unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \
  sys/ioctl.h malloc.h sys/malloc.h sys/ipc.h sys/shm.h linux/config.h \
- sys/resource.h sys/param.h)
+ sys/resource.h sys/param.h port.h)
 
 AC_CHECK_HEADERS([xfs/xfs.h])
 
@@ -983,7 +983,7 @@ case $SYSTEM_TYPE in
     AC_DEFINE([DEFAULT_SKIP_THREAD_PRIORITY], [1], [default to skip thread priority])
     if test "$ac_cv_prog_gcc" = "yes"
     then
-      FLAGS="-D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DIGNORE_SIGHUP_SIGQUIT"
+      FLAGS="-D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DIGNORE_SIGHUP_SIGQUIT  -DDONT_DECLARE_CXA_PURE_VIRTUAL"
       CFLAGS="$CFLAGS $FLAGS"
       CXXFLAGS="$CXXFLAGS $FLAGS"
       MAX_C_OPTIMIZE="-O"
@@ -1883,9 +1883,9 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bs
   pthread_setprio_np pthread_setschedparam pthread_sigmask readlink \
   realpath rename rint rwlock_init setupterm \
   shmget shmat shmdt shmctl sigaction sigemptyset sigaddset \
-  sighold sigset sigthreadmask sleep \
-  snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr strtol \
-  strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr \
+  sighold sigset sigthreadmask port_create sleep \
+  snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr \
+  strtol strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr \
   posix_fallocate)
 
 #

--- 1.229/sql/handler.cc	2007-02-21 22:20:13 +04:00
+++ 1.230/sql/handler.cc	2007-02-28 18:27:03 +04:00
@@ -845,7 +845,7 @@ int ha_rollback_trans(THD *thd, bool all
     message in the error log, so we don't send it.
   */
   if (is_real_trans && (thd->options & OPTION_STATUS_NO_TRANS_UPDATE) &&
-      !thd->slave_thread)
+      !thd->slave_thread && thd->killed != THD::KILL_CONNECTION)
     push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                  ER_WARNING_NOT_COMPLETE_ROLLBACK,
                  ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
@@ -2855,8 +2855,8 @@ ha_find_files(THD *thd,const char *db,co
 {
   int error= 0;
   DBUG_ENTER("ha_find_files");
-  DBUG_PRINT("enter", ("db: %s, path: %s, wild: %s, dir: %d", 
-		       db, path, wild, dir));
+  DBUG_PRINT("enter", ("db: '%s'  path: '%s'  wild: '%s'  dir: %d", 
+		       db, path, wild ? wild : "NULL", dir));
   st_find_files_args args= {db, path, wild, dir, files};
 
   plugin_foreach(thd, find_files_handlerton,

--- 1.185/sql/item.cc	2007-02-21 22:20:13 +04:00
+++ 1.186/sql/item.cc	2007-02-28 18:27:04 +04:00
@@ -1553,6 +1553,8 @@ bool agg_item_charsets(DTCollation &coll
       doesn't display each argument's characteristics.
     - if nargs is 1, then this error cannot happen.
   */
+  LINT_INIT(safe_args[0]);
+  LINT_INIT(safe_args[1]);
   if (nargs >=2 && nargs <= 3)
   {
     safe_args[0]= args[0];
@@ -1637,7 +1639,7 @@ void Item_ident_for_show::make_field(Sen
 Item_field::Item_field(Field *f)
   :Item_ident(0, NullS, *f->table_name, f->field_name),
    item_equal(0), no_const_subst(0),
-   have_privileges(0), any_privileges(0)
+   have_privileges(0), any_privileges(0), fixed_as_field(0)
 {
   set_field(f);
   /*
@@ -1652,7 +1654,7 @@ Item_field::Item_field(THD *thd, Name_re
                        Field *f)
   :Item_ident(context_arg, f->table->s->db.str, *f->table_name, f->field_name),
    item_equal(0), no_const_subst(0),
-   have_privileges(0), any_privileges(0)
+   have_privileges(0), any_privileges(0), fixed_as_field(0)
 {
   /*
     We always need to provide Item_field with a fully qualified field
@@ -1691,9 +1693,12 @@ Item_field::Item_field(Name_resolution_c
                        const char *field_name_arg)
   :Item_ident(context_arg, db_arg,table_name_arg,field_name_arg),
    field(0), result_field(0), item_equal(0), no_const_subst(0),
-   have_privileges(0), any_privileges(0)
+   have_privileges(0), any_privileges(0), fixed_as_field(0)
 {
+  SELECT_LEX *select= current_thd->lex->current_select;
   collation.set(DERIVATION_IMPLICIT);
+  if (select && select->parsing_place != IN_HAVING)
+      select->select_n_where_fields++;
 }
 
 // Constructor need to process subselect with temporary tables (see Item)
@@ -1704,7 +1709,8 @@ Item_field::Item_field(THD *thd, Item_fi
    item_equal(item->item_equal),
    no_const_subst(item->no_const_subst),
    have_privileges(item->have_privileges),
-   any_privileges(item->any_privileges)
+   any_privileges(item->any_privileges),
+   fixed_as_field(item->fixed_as_field)
 {
   collation.set(DERIVATION_IMPLICIT);
 }
@@ -3515,8 +3521,46 @@ Item_field::fix_outer_field(THD *thd, Fi
         }
         if (*from_field != view_ref_found)
         {
+
           prev_subselect_item->used_tables_cache|= (*from_field)->table->map;
           prev_subselect_item->const_item_cache= 0;
+          if (!last_checked_context->select_lex->having_fix_field &&
+              !fixed_as_field)
+          {
+            Item_outer_ref *rf;
+            Query_arena *arena= 0, backup;
+            /*
+              Each outer field is replaced for an Item_outer_ref object.
+              This is done in order to get correct results when the outer
+              select employs a temporary table.
+              The original fields are saved in the inner_fields_list of the
+              outer select. This list is created by the following reasons:
+              1. We can't add field items to the outer select list directly
+                 because the outer select hasn't been fully fixed yet.
+              2. We need a location to refer to in the Item_ref object
+                 so the inner_fields_list is used as such temporary
+                 reference storage.
+              The new Item_outer_ref object replaces the original field and is
+              also saved in the inner_refs_list of the outer select. Here
+              it is only created. It can be fixed only after the original
+              field has been fixed and this is done in the fix_inner_refs()
+              function.
+            */
+            set_field(*from_field);
+            arena= thd->activate_stmt_arena_if_needed(&backup);
+            rf= new Item_outer_ref(context, this);
+            if (!rf)
+            {
+              if (arena)
+                thd->restore_active_arena(arena, &backup);
+              return -1;
+            }
+            *reference= rf;
+            select->inner_refs_list.push_back(rf);
+            if (arena)
+              thd->restore_active_arena(arena, &backup);
+            fixed_as_field= 1;
+          }
           if (thd->lex->in_sum_func &&
               thd->lex->in_sum_func->nest_level == 
               thd->lex->current_select->nest_level)
@@ -3644,7 +3688,7 @@ Item_field::fix_outer_field(THD *thd, Fi
   {
     mark_as_dependent(thd, last_checked_context->select_lex,
                       context->select_lex,
-                      this, this);
+                      this, (Item_ident*)*reference);
     if (last_checked_context->select_lex->having_fix_field)
     {
       Item_ref *rf;
@@ -4893,6 +4937,51 @@ void Item_field::update_null_value() 
 }
 
 
+/*
+  Add the field to the select list and substitute it for the reference to
+  the field.
+
+  SYNOPSIS
+    Item_field::update_value_transformer()
+    select_arg      current select
+
+  DESCRIPTION
+    If the field doesn't belong to the table being inserted into then it is
+    added to the select list, pointer to it is stored in the ref_pointer_array
+    of the select and the field itself is substituted for the Item_ref object.
+    This is done in order to get correct values from update fields that
+    belongs to the SELECT part in the INSERT .. SELECT .. ON DUPLICATE KEY
+    UPDATE statement.
+
+  RETURN
+    0             if error occured
+    ref           if all conditions are met
+    this field    otherwise
+*/
+
+Item *Item_field::update_value_transformer(byte *select_arg)
+{
+  SELECT_LEX *select= (SELECT_LEX*)select_arg;
+  DBUG_ASSERT(fixed);
+
+  if (field->table != select->context.table_list->table &&
+      type() != Item::TRIGGER_FIELD_ITEM)
+  {
+    List<Item> *all_fields= &select->join->all_fields;
+    Item **ref_pointer_array= select->ref_pointer_array;
+    int el= all_fields->elements;
+    Item_ref *ref;
+
+    ref_pointer_array[el]= (Item*)this;
+    all_fields->push_front((Item*)this);
+    ref= new Item_ref(&select->context, ref_pointer_array + el,
+                      table_name, field_name);
+    return ref;
+  }
+  return this;
+}
+
+
 Item_ref::Item_ref(Name_resolution_context *context_arg,
                    Item **item, const char *table_name_arg,
                    const char *field_name_arg)
@@ -4902,8 +4991,7 @@ Item_ref::Item_ref(Name_resolution_conte
   /*
     This constructor used to create some internals references over fixed items
   */
-  DBUG_ASSERT(ref != 0);
-  if (*ref && (*ref)->fixed)
+  if (ref && *ref && (*ref)->fixed)
     set_properties();
 }
 
@@ -5204,7 +5292,7 @@ void Item_ref::print(String *str)
   if (ref)
   {
     if ((*ref)->type() != Item::CACHE_ITEM && ref_type() != VIEW_REF &&
-        name && alias_name_used)
+        ref_type() != OUTER_REF && name && alias_name_used)
     {
       THD *thd= current_thd;
       append_identifier(thd, str, name, (uint) strlen(name));
@@ -5452,7 +5540,7 @@ bool Item_direct_ref::get_date(TIME *lti
 
 
 /*
-  Prepare referenced view viewld then call usual Item_direct_ref::fix_fields
+  Prepare referenced field then call usual Item_direct_ref::fix_fields
 
   SYNOPSIS
     Item_direct_view_ref::fix_fields()
@@ -5472,6 +5560,31 @@ bool Item_direct_view_ref::fix_fields(TH
   if (!(*ref)->fixed &&
       ((*ref)->fix_fields(thd, ref)))
     return TRUE;
+  return Item_direct_ref::fix_fields(thd, reference);
+}
+
+/*
+  Prepare referenced outer field then call usual Item_direct_ref::fix_fields
+
+  SYNOPSIS
+    Item_outer_ref::fix_fields()
+    thd         thread handler
+    reference   reference on reference where this item stored
+
+  RETURN
+    FALSE   OK
+    TRUE    Error
+*/
+
+bool Item_outer_ref::fix_fields(THD *thd, Item **reference)
+{
+  DBUG_ASSERT(*ref);
+  /* outer_field->check_cols() will be made in Item_direct_ref::fix_fields */
+  outer_field->fixed_as_field= 1;
+  if (!outer_field->fixed &&
+      (outer_field->fix_fields(thd, reference)))
+    return TRUE;
+  table_name= outer_field->table_name;
   return Item_direct_ref::fix_fields(thd, reference);
 }
 

--- 1.205/sql/item.h	2007-02-21 22:20:13 +04:00
+++ 1.206/sql/item.h	2007-02-28 18:27:04 +04:00
@@ -325,10 +325,10 @@ private:
   TABLE_LIST *save_first_name_resolution_table;
   TABLE_LIST *save_next_name_resolution_table;
   bool        save_resolve_in_select_list;
+  TABLE_LIST *save_next_local;
 
 public:
   Name_resolution_context_state() {}          /* Remove gcc warning */
-  TABLE_LIST *save_next_local;
 
 public:
   /* Save the state of a name resolution context. */
@@ -350,6 +350,11 @@ public:
     context->first_name_resolution_table=  save_first_name_resolution_table;
     context->resolve_in_select_list=       save_resolve_in_select_list;
   }
+
+  TABLE_LIST *get_first_name_resolution_table()
+  {
+    return save_first_name_resolution_table;
+  }
 };
 
 
@@ -912,6 +917,7 @@ public:
   virtual Item_field *filed_for_view_update() { return 0; }
 
   virtual Item *neg_transformer(THD *thd) { return NULL; }
+  virtual Item *update_value_transformer(byte *select_arg) { return this; }
   virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
   void delete_self()
   {
@@ -1311,7 +1317,7 @@ public:
   uint have_privileges;
   /* field need any privileges (for VIEW creation) */
   bool any_privileges;
-
+  bool fixed_as_field;
   Item_field(Name_resolution_context *context_arg,
              const char *db_arg,const char *table_name_arg,
 	     const char *field_name_arg);
@@ -1391,6 +1397,7 @@ public:
   Item_field *filed_for_view_update() { return this; }
   Item *safe_charset_converter(CHARSET_INFO *tocs);
   int fix_outer_field(THD *thd, Field **field, Item **reference);
+  virtual Item *update_value_transformer(byte *select_arg);
   friend class Item_default_value;
   friend class Item_insert_value;
   friend class st_select_lex_unit;
@@ -1921,7 +1928,7 @@ class Item_ref :public Item_ident
 protected:
   void set_properties();
 public:
-  enum Ref_Type { REF, DIRECT_REF, VIEW_REF };
+  enum Ref_Type { REF, DIRECT_REF, VIEW_REF, OUTER_REF };
   Field *result_field;			 /* Save result here */
   Item **ref;
   Item_ref(Name_resolution_context *context_arg,
@@ -1982,7 +1989,7 @@ public:
                           (*ref)->get_tmp_table_item(thd));
   }
   table_map used_tables() const		
-  { 
+  {
     return depended_from ? OUTER_REF_TABLE_BIT : (*ref)->used_tables(); 
   }
   table_map not_null_tables() const { return (*ref)->not_null_tables(); }
@@ -2052,6 +2059,40 @@ public:
   bool fix_fields(THD *, Item **);
   bool eq(const Item *item, bool binary_cmp) const;
   virtual Ref_Type ref_type() { return VIEW_REF; }
+};
+
+
+class Item_outer_ref :public Item_direct_ref
+{
+public:
+  Item_field *outer_field;
+  Item_outer_ref(Name_resolution_context *context_arg,
+                 Item_field *outer_field_arg)
+    :Item_direct_ref(context_arg, 0, outer_field_arg->table_name,
+                          outer_field_arg->field_name),
+    outer_field(outer_field_arg)
+  {
+    ref= (Item**)&outer_field;
+    set_properties();
+    fixed= 0;
+  }
+  void cleanup()
+  {
+    ref= (Item**)&outer_field;
+    fixed= 0;
+    Item_direct_ref::cleanup();
+    outer_field->cleanup();
+  }
+  void save_in_result_field(bool no_conversions)
+  {
+    outer_field->save_org_in_field(result_field);
+  }
+  bool fix_fields(THD *, Item **);
+  table_map used_tables() const
+  {
+    return (*ref)->const_item() ? 0 : OUTER_REF_TABLE_BIT;
+  }
+  virtual Ref_Type ref_type() { return OUTER_REF; }
 };
 
 

--- 1.356/sql/item_func.cc	2007-02-21 22:20:13 +04:00
+++ 1.357/sql/item_func.cc	2007-02-28 18:27:04 +04:00
@@ -3087,14 +3087,8 @@ public:
   int count;
   bool locked;
   pthread_cond_t cond;
-#ifndef EMBEDDED_LIBRARY
-  pthread_t thread;
-  void set_thread(THD *thd) { thread= thd->real_id; }
-#else
-  THD       *thread;
-  void set_thread(THD *thd) { thread= thd; }
-#endif /*EMBEDDED_LIBRARY*/
-  ulong thread_id;
+  my_thread_id thread_id;
+  void set_thread(THD *thd) { thread_id= thd->thread_id; }
 
   User_level_lock(const char *key_arg,uint length, ulong id) 
     :key_length(length),count(1),locked(1), thread_id(id)
@@ -3411,11 +3405,7 @@ longlong Item_func_release_lock::val_int
   }
   else
   {
-#ifdef EMBEDDED_LIBRARY
-    if (ull->locked && (current_thd == ull->thread))
-#else
-    if (ull->locked && pthread_equal(pthread_self(),ull->thread))
-#endif
+    if (ull->locked && current_thd->thread_id == ull->thread_id)
     {
       result=1;					// Release is ok
       item_user_lock_release(ull);
@@ -3460,7 +3450,7 @@ longlong Item_func_benchmark::val_int()
   THD *thd=current_thd;
   ulong loop_count;
 
-  loop_count= args[0]->val_int();
+  loop_count= (ulong) args[0]->val_int();
 
   if (args[0]->null_value)
   {

--- 1.100/sql/lock.cc	2007-02-22 06:27:37 +04:00
+++ 1.101/sql/lock.cc	2007-02-28 18:27:04 +04:00
@@ -485,7 +485,7 @@ bool mysql_lock_abort_for_thread(THD *th
     for (uint i=0; i < locked->lock_count; i++)
     {
       if (thr_abort_locks_for_thread(locked->locks[i]->lock,
-                                     table->in_use->real_id))
+                                     table->in_use->thread_id))
         result= TRUE;
     }
     my_free((gptr) locked,MYF(0));

--- 1.267/sql/log_event.cc	2007-02-21 22:20:14 +04:00
+++ 1.268/sql/log_event.cc	2007-02-28 18:27:04 +04:00
@@ -1148,7 +1148,6 @@ void Log_event::print_base64(IO_CACHE* f
 {
   const uchar *ptr= (const uchar *)temp_buf;
   uint32 size= uint4korr(ptr + EVENT_LEN_OFFSET);
-
   DBUG_ENTER("Log_event::print_base64");
 
   size_t const tmp_str_sz= base64_needed_encoded_length((int) size);
@@ -1159,8 +1158,10 @@ void Log_event::print_base64(IO_CACHE* f
     DBUG_VOID_RETURN;
   }
 
-  int const res= base64_encode(ptr, (size_t) size, tmp_str);
-  DBUG_ASSERT(res == 0);
+  if (base64_encode(ptr, (size_t) size, tmp_str))
+  {
+    DBUG_ASSERT(0);
+  }
 
   if (my_b_tell(file) == 0)
     my_b_printf(file, "\nBINLOG '\n");
@@ -5471,7 +5472,7 @@ int Rows_log_event::do_add_row_data(byte
     my_ptrdiff_t const new_alloc= 
         block_size * ((cur_size + length) / block_size + block_size - 1);
 
-    byte* const new_buf= (byte*)my_realloc((gptr)m_rows_buf, new_alloc,
+    byte* const new_buf= (byte*)my_realloc((gptr)m_rows_buf, (uint) new_alloc,
                                            MYF(MY_ALLOW_ZERO_PTR|MY_WME));
     if (unlikely(!new_buf))
       DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@@ -6014,7 +6015,7 @@ bool Rows_log_event::write_data_body(IO_
                           sbuf_end - sbuf) ||
           my_b_safe_write(file, reinterpret_cast<byte*>(m_cols.bitmap),
                           no_bytes_in_map(&m_cols)) ||
-          my_b_safe_write(file, m_rows_buf, data_size));
+          my_b_safe_write(file, m_rows_buf, (uint) data_size));
 }
 #endif
 
@@ -6367,8 +6368,8 @@ bool Table_map_log_event::write_data_bod
   DBUG_ASSERT(m_dblen < 128);
   DBUG_ASSERT(m_tbllen < 128);
 
-  byte const dbuf[]= { m_dblen };
-  byte const tbuf[]= { m_tbllen };
+  byte const dbuf[]= { (byte) m_dblen };
+  byte const tbuf[]= { (byte) m_tbllen };
 
   char cbuf[sizeof(m_colcnt)];
   char *const cbuf_end= net_store_length((char*) cbuf, (uint) m_colcnt);

--- 1.302/sql/slave.cc	2007-02-23 02:57:12 +04:00
+++ 1.303/sql/slave.cc	2007-02-28 18:27:04 +04:00
@@ -1425,9 +1425,8 @@ static int init_slave_thread(THD* thd, S
   thd->slave_thread = 1;
   set_slave_thread_options(thd);
   thd->client_capabilities = CLIENT_LOCAL_FILES;
-  thd->real_id=pthread_self();
   pthread_mutex_lock(&LOCK_thread_count);
-  thd->thread_id = thread_id++;
+  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
   pthread_mutex_unlock(&LOCK_thread_count);
 
   if (init_thr_lock() || thd->store_globals())
@@ -1436,12 +1435,6 @@ static int init_slave_thread(THD* thd, S
     delete thd;
     DBUG_RETURN(-1);
   }
-
-#if !defined(__WIN__) && !defined(__NETWARE__)
-  sigset_t set;
-  VOID(sigemptyset(&set));                      // Get mask in use
-  VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
-#endif
 
   if (thd_type == SLAVE_THD_SQL)
     THD_SET_PROC_INFO(thd, "Waiting for the next event in relay log");

--- 1.375/sql/sql_base.cc	2007-02-21 22:20:14 +04:00
+++ 1.376/sql/sql_base.cc	2007-02-28 18:27:04 +04:00
@@ -1078,7 +1078,6 @@ void close_thread_tables(THD *thd, bool 
   if (!thd->active_transaction())
     thd->transaction.xid_state.xid.null();
 
-  /* VOID(pthread_sigmask(SIG_SETMASK,&thd->block_signals,NULL)); */
   if (!lock_in_use)
     VOID(pthread_mutex_lock(&LOCK_open));
 
@@ -1208,11 +1207,12 @@ void close_temporary_tables(THD *thd)
   const char stub[]= "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ";
   uint stub_len= sizeof(stub) - 1;
   char buf[256];
-  memcpy(buf, stub, stub_len);
   String s_query= String(buf, sizeof(buf), system_charset_info);
-  bool found_user_tables= false;
+  bool found_user_tables= FALSE;
   LINT_INIT(next);
 
+  memcpy(buf, stub, stub_len);
+
   /*
      insertion sort of temp tables by pseudo_thread_id to build ordered list
      of sublists of equal pseudo_thread_id
@@ -1263,10 +1263,13 @@ void close_temporary_tables(THD *thd)
   {
     if (is_user_table(table))
     {
+      my_thread_id save_pseudo_thread_id= thd->variables.pseudo_thread_id;
       /* Set pseudo_thread_id to be that of the processed table */
       thd->variables.pseudo_thread_id= tmpkeyval(thd, table);
-      /* Loop forward through all tables within the sublist of
-         common pseudo_thread_id to create single DROP query */
+      /*
+        Loop forward through all tables within the sublist of
+        common pseudo_thread_id to create single DROP query.
+      */
       for (s_query.length(stub_len);
            table && is_user_table(table) &&
              tmpkeyval(thd, table) == thd->variables.pseudo_thread_id;
@@ -1292,16 +1295,18 @@ void close_temporary_tables(THD *thd)
                             0, FALSE);
       thd->variables.character_set_client= cs_save;
       /*
-        Imagine the thread had created a temp table, then was doing a SELECT, and
-        the SELECT was killed. Then it's not clever to mark the statement above as
-        "killed", because it's not really a statement updating data, and there
-        are 99.99% chances it will succeed on slave.
-        If a real update (one updating a persistent table) was killed on the
-        master, then this real update will be logged with error_code=killed,
-        rightfully causing the slave to stop.
+        Imagine the thread had created a temp table, then was doing a
+        SELECT, and the SELECT was killed. Then it's not clever to
+        mark the statement above as "killed", because it's not really
+        a statement updating data, and there are 99.99% chances it
+        will succeed on slave.  If a real update (one updating a
+        persistent table) was killed on the master, then this real
+        update will be logged with error_code=killed, rightfully
+        causing the slave to stop.
       */
       qinfo.error_code= 0;
       mysql_bin_log.write(&qinfo);
+      thd->variables.pseudo_thread_id= save_pseudo_thread_id;
     }
     else
     {
@@ -1519,9 +1524,15 @@ TABLE *find_temporary_table(THD *thd, TA
   {
     if (table->s->table_cache_key.length == key_length &&
 	!memcmp(table->s->table_cache_key.str, key, key_length))
+    {
+      DBUG_PRINT("info",
+                 ("Found table. server_id: %u  pseudo_thread_id: %lu",
+                  (uint) thd->server_id,
+                  (ulong) thd->variables.pseudo_thread_id));
       DBUG_RETURN(table);
+    }
   }
-  DBUG_RETURN(0);					// Not a temporary table
+  DBUG_RETURN(0);                               // Not a temporary table
 }
 
 
@@ -1857,6 +1868,10 @@ TABLE *open_table(THD *thd, TABLE_LIST *
 	if (table->query_id == thd->query_id ||
             thd->prelocked_mode && table->query_id)
 	{
+          DBUG_PRINT("error",
+                     ("query_id: %lu  server_id: %u  pseudo_thread_id: %lu",
+                      (ulong) table->query_id, (uint) thd->server_id,
+                      (ulong) thd->variables.pseudo_thread_id));
 	  my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
 	  DBUG_RETURN(0);
 	}
@@ -3507,8 +3522,11 @@ TABLE *open_temporary_table(THD *thd, co
   uint key_length;
   TABLE_LIST table_list;
   DBUG_ENTER("open_temporary_table");
-  DBUG_PRINT("enter", ("table: '%s'.'%s'  path: '%s'",
-                       db, table_name, path));
+  DBUG_PRINT("enter",
+             ("table: '%s'.'%s'  path: '%s'  server_id: %u  "
+              "pseudo_thread_id: %lu",
+              db, table_name, path,
+              (uint) thd->server_id, (ulong) thd->variables.pseudo_thread_id));
 
   table_list.db=         (char*) db;
   table_list.table_name= (char*) table_name;
@@ -3795,6 +3813,7 @@ find_field_in_natural_join(THD *thd, TAB
   if (nj_col->view_field)
   {
     Item *item;
+    LINT_INIT(arena);
     if (register_tree_change)
       arena= thd->activate_stmt_arena_if_needed(&backup);
     /*
@@ -3978,6 +3997,9 @@ find_field_in_table_ref(THD *thd, TABLE_
 {
   Field *fld;
   DBUG_ENTER("find_field_in_table_ref");
+  DBUG_ASSERT(table_list->alias);
+  DBUG_ASSERT(name);
+  DBUG_ASSERT(item_name);
   DBUG_PRINT("enter",
              ("table: '%s'  field name: '%s'  item name: '%s'  ref 0x%lx",
               table_list->alias, name, item_name, (ulong) ref));
@@ -5443,21 +5465,8 @@ bool setup_tables(THD *thd, Name_resolut
   uint tablenr= 0;
   DBUG_ENTER("setup_tables");
 
-  /*
-    Due to the various call paths that lead to setup_tables() it may happen
-    that context->table_list and context->first_name_resolution_table can be
-    NULL (this is typically done when creating TABLE_LISTs internally).
-    TODO:
-    Investigate all cases when this my happen, initialize the name resolution
-    context correctly in all those places, and remove the context reset below.
-  */
-  if (!context->table_list || !context->first_name_resolution_table)
-  {
-    /* Test whether the context is in a consistent state. */
-    DBUG_ASSERT(!context->first_name_resolution_table && !context->table_list);
-    context->table_list= context->first_name_resolution_table= tables;
-  }
-
+  DBUG_ASSERT ((select_insert && !tables->next_name_resolution_table) || !tables || 
+               (context->table_list && context->first_name_resolution_table));
   /*
     this is used for INSERT ... SELECT.
     For select we setup tables except first (and its underlying tables)

--- 1.313/sql/sql_class.cc	2007-02-21 22:20:14 +04:00
+++ 1.314/sql/sql_class.cc	2007-02-28 18:27:04 +04:00
@@ -243,7 +243,7 @@ THD::THD()
   time_after_lock=(time_t) 0;
   current_linfo =  0;
   slave_thread = 0;
-  variables.pseudo_thread_id= 0;
+  thread_id= variables.pseudo_thread_id= 0;
   one_shot_set= 0;
   file_id = 0;
   query_id= 0;
@@ -267,9 +267,6 @@ THD::THD()
   cleanup_done= abort_on_warning= no_warnings_for_error= 0;
   peer_port= 0;					// For SHOW PROCESSLIST
   transaction.m_pending_rows_event= 0;
-#ifdef	__WIN__
-  real_id = 0;
-#endif
 #ifdef SIGNAL_WITH_VIO_CLOSE
   active_vio = 0;
 #endif
@@ -401,6 +398,8 @@ void THD::change_user(void)
 void THD::cleanup(void)
 {
   DBUG_ENTER("THD::cleanup");
+  DBUG_ASSERT(cleanup_done == 0);
+
 #ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
   if (transaction.xid_state.xa_state == XA_PREPARED)
   {
@@ -436,7 +435,6 @@ void THD::cleanup(void)
     pthread_mutex_lock(&LOCK_user_locks);
     item_user_lock_release(ull);
     pthread_mutex_unlock(&LOCK_user_locks);
-    ull= 0;
   }
 
   cleanup_done=1;
@@ -572,7 +570,9 @@ void THD::awake(THD::killed_state state_
   killed= state_to_set;
   if (state_to_set != THD::KILL_QUERY)
   {
-    thr_alarm_kill(real_id);
+    thr_alarm_kill(thread_id);
+    if (!slave_thread)
+      thread_scheduler.post_kill_notification(this);
 #ifdef SIGNAL_WITH_VIO_CLOSE
     close_active_vio();
 #endif    
@@ -623,18 +623,19 @@ bool THD::store_globals()
     Assert that thread_stack is initialized: it's necessary to be able
     to track stack overrun.
   */
-  DBUG_ASSERT(this->thread_stack);
+  DBUG_ASSERT(thread_stack);
 
   if (my_pthread_setspecific_ptr(THR_THD,  this) ||
       my_pthread_setspecific_ptr(THR_MALLOC, &mem_root))
     return 1;
   mysys_var=my_thread_var;
-  dbug_thread_id=my_thread_id();
   /*
-    By default 'slave_proxy_id' is 'thread_id'. They may later become different
-    if this is the slave SQL thread.
+    Let mysqld define the thread id (not mysys)
+    This allows us to move THD to different threads if needed.
   */
-  variables.pseudo_thread_id= thread_id;
+  mysys_var->id= thread_id;
+  real_id= pthread_self();                      // For debugging
+
   /*
     We have to call thr_lock_info_init() again here as THD may have been
     created in another thread
@@ -2533,7 +2534,7 @@ my_size_t THD::pack_row(TABLE *table, MY
     if (bitmap_is_set(cols,i))
     {
       my_ptrdiff_t const offset=
-        field->is_null(rec_offset) ? def_offset : rec_offset;
+        field->is_null((uint) rec_offset) ? def_offset : rec_offset;
       field->move_field_offset(offset);
       ptr= (byte*)field->pack((char *) ptr, field->ptr);
       field->move_field_offset(-offset);
@@ -2575,7 +2576,7 @@ namespace {
       : m_memory(0)
     {
 #ifndef DBUG_OFF
-      m_alloc_checked= false;
+      m_alloc_checked= FALSE;
 #endif
       allocate_memory(table, len1);
       m_ptr[0]= has_memory() ? m_memory : 0;
@@ -2586,7 +2587,7 @@ namespace {
       : m_memory(0)
     {
 #ifndef DBUG_OFF
-      m_alloc_checked= false;
+      m_alloc_checked= FALSE;
 #endif
       allocate_memory(table, len1 + len2);
       m_ptr[0]= has_memory() ? m_memory        : 0;
@@ -2607,7 +2608,7 @@ namespace {
      */
     bool has_memory() const {
 #ifndef DBUG_OFF
-      m_alloc_checked= true;
+      m_alloc_checked= TRUE;
 #endif
       return m_memory != 0;
     }
@@ -2616,7 +2617,7 @@ namespace {
     {
       DBUG_ASSERT(s < sizeof(m_ptr)/sizeof(*m_ptr));
       DBUG_ASSERT(m_ptr[s] != 0);
-      DBUG_ASSERT(m_alloc_checked == true);
+      DBUG_ASSERT(m_alloc_checked == TRUE);
       return m_ptr[s];
     }
 
@@ -2646,12 +2647,12 @@ namespace {
           table->write_row_record=
             (byte *) alloc_root(&table->mem_root, 2 * maxlen);
         m_memory= table->write_row_record;
-        m_release_memory_on_destruction= false;
+        m_release_memory_on_destruction= FALSE;
       }
       else
       {
         m_memory= (byte *) my_malloc(total_length, MYF(MY_WME));
-        m_release_memory_on_destruction= true;
+        m_release_memory_on_destruction= TRUE;
       }
     }
 

--- 1.340/sql/sql_class.h	2007-02-21 22:20:15 +04:00
+++ 1.341/sql/sql_class.h	2007-02-28 18:27:04 +04:00
@@ -214,7 +214,7 @@ struct system_variables
   ulong read_rnd_buff_size;
   ulong div_precincrement;
   ulong sortbuff_size;
-  handlerton *table_type;
+  ulong thread_handling;
   ulong tx_isolation;
   ulong completion_type;
   /* Determines which non-standard SQL behaviour should be enabled */
@@ -231,11 +231,15 @@ struct system_variables
   ulong trans_prealloc_size;
   ulong log_warnings;
   ulong group_concat_max_len;
+  ulong ndb_autoincrement_prefetch_sz;
+  ulong ndb_index_stat_cache_entries;
+  ulong ndb_index_stat_update_freq;
+  ulong binlog_format; // binlog format for this thd (see enum_binlog_format)
   /*
     In slave thread we need to know in behalf of which
     thread the query is being run to replicate temp tables properly
   */
-  ulong pseudo_thread_id;
+  my_thread_id pseudo_thread_id;
 
   my_bool low_priority_updates;
   my_bool new_mode;
@@ -248,14 +252,12 @@ struct system_variables
   my_bool ndb_use_exact_count;
   my_bool ndb_use_transactions;
   my_bool ndb_index_stat_enable;
-  ulong ndb_autoincrement_prefetch_sz;
-  ulong ndb_index_stat_cache_entries;
-  ulong ndb_index_stat_update_freq;
-  ulong binlog_format; // binlog format for this thd (see enum_binlog_format)
 
   my_bool old_alter_table;
   my_bool old_passwords;
 
+  handlerton *table_type;
+
   /* Only charset part of these variables is sensible */
   CHARSET_INFO  *character_set_filesystem;
   CHARSET_INFO  *character_set_client;
@@ -1078,7 +1080,7 @@ public:
   } transaction;
   Field      *dup_field;
 #ifndef __WIN__
-  sigset_t signals,block_signals;
+  sigset_t signals;
 #endif
 #ifdef SIGNAL_WITH_VIO_CLOSE
   Vio* active_vio;
@@ -1269,7 +1271,7 @@ public:
     update auto-updatable fields (like auto_increment and timestamp).
   */
   query_id_t query_id, warn_id;
-  ulong      thread_id, col_access;
+  ulong      col_access;
 
 #ifdef ERROR_INJECT_SUPPORT
   ulong      error_inject_value;
@@ -1278,8 +1280,8 @@ public:
   ulong      statement_id_counter;
   ulong	     rand_saved_seed1, rand_saved_seed2;
   ulong      row_count;  // Row counter, mainly for errors and warnings
-  long	     dbug_thread_id;
-  pthread_t  real_id;
+  pthread_t  real_id;                           /* For debugging */
+  my_thread_id  thread_id;
   uint	     tmp_table, global_read_lock;
   uint	     server_status,open_options;
   enum enum_thread_type system_thread;
@@ -1643,6 +1645,7 @@ public:
     *p_db_length= db_length;
     return FALSE;
   }
+  thd_scheduler scheduler;
 };
 
 

--- 1.206/sql/sql_delete.cc	2007-02-21 22:20:15 +04:00
+++ 1.207/sql/sql_delete.cc	2007-02-28 18:27:05 +04:00
@@ -377,6 +377,7 @@ bool mysql_prepare_delete(THD *thd, TABL
   Item *fake_conds= 0;
   SELECT_LEX *select_lex= &thd->lex->select_lex;
   DBUG_ENTER("mysql_prepare_delete");
+  List<Item> all_fields;
 
   thd->lex->allow_sum_func= 0;
   if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
@@ -400,6 +401,11 @@ bool mysql_prepare_delete(THD *thd, TABL
       DBUG_RETURN(TRUE);
     }
   }
+
+  if (select_lex->inner_refs_list.elements &&
+    fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
+    DBUG_RETURN(-1);
+
   select_lex->fix_prepare_information(thd, conds, &fake_conds);
   DBUG_RETURN(FALSE);
 }

--- 1.247/sql/sql_insert.cc	2007-02-21 22:20:15 +04:00
+++ 1.248/sql/sql_insert.cc	2007-02-28 18:27:05 +04:00
@@ -396,6 +396,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
 #ifndef EMBEDDED_LIBRARY
   if (lock_type == TL_WRITE_DELAYED)
   {
+    res= 1;
     if (thd->locked_tables)
     {
       DBUG_ASSERT(table_list->db); /* Must be set in the parser */
@@ -946,6 +947,8 @@ bool mysql_prepare_insert(THD *thd, TABL
   DBUG_PRINT("enter", ("table_list 0x%lx, table 0x%lx, view %d",
 		       (ulong)table_list, (ulong)table,
 		       (int)insert_into_view));
+  /* INSERT should have a SELECT or VALUES clause */
+  DBUG_ASSERT (!select_insert || !values);
 
   /*
     For subqueries in VALUES() we should not see the table in which we are
@@ -977,44 +980,40 @@ bool mysql_prepare_insert(THD *thd, TABL
   if (mysql_prepare_insert_check_table(thd, table_list, fields, select_insert))
     DBUG_RETURN(TRUE);
 
-  /* Save the state of the current name resolution context. */
-  ctx_state.save_state(context, table_list);
-
-  /*
-    Perform name resolution only in the first table - 'table_list',
-    which is the table that is inserted into.
-  */
-  table_list->next_local= 0;
-  context->resolve_in_table_list_only(table_list);
 
   /* Prepare the fields in the statement. */
-  if (values &&
-      !(res= check_insert_fields(thd, context->table_list, fields, *values,
-                                 !insert_into_view, &map) ||
-        setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0)) &&
-      duplic == DUP_UPDATE)
+  if (values)
   {
-    select_lex->no_wrap_view_item= TRUE;
-    res= check_update_fields(thd, context->table_list, update_fields, &map);
-    select_lex->no_wrap_view_item= FALSE;
+    /* if we have INSERT ... VALUES () we cannot have a GROUP BY clause */
+    DBUG_ASSERT (!select_lex->group_list.elements);
+
+    /* Save the state of the current name resolution context. */
+    ctx_state.save_state(context, table_list);
+
     /*
-      When we are not using GROUP BY we can refer to other tables in the
-      ON DUPLICATE KEY part.
-    */       
-    if (select_lex->group_list.elements == 0)
-    {
-      context->table_list->next_local=       ctx_state.save_next_local;
-      /* first_name_resolution_table was set by resolve_in_table_list_only() */
-      context->first_name_resolution_table->
-        next_name_resolution_table=          ctx_state.save_next_local;
+      Perform name resolution only in the first table - 'table_list',
+      which is the table that is inserted into.
+     */
+    table_list->next_local= 0;
+    context->resolve_in_table_list_only(table_list);
+
+    if (!(res= check_insert_fields(thd, context->table_list, fields, *values,
+                                 !insert_into_view, &map) ||
+          setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0)) 
+        && duplic == DUP_UPDATE)
+    {
+      select_lex->no_wrap_view_item= TRUE;
+      res= check_update_fields(thd, context->table_list, update_fields, &map);
+      select_lex->no_wrap_view_item= FALSE;
     }
+
+    /* Restore the current context. */
+    ctx_state.restore_state(context, table_list);
+
     if (!res)
       res= setup_fields(thd, 0, update_values, MARK_COLUMNS_READ, 0, 0);
   }
 
-  /* Restore the current context. */
-  ctx_state.restore_state(context, table_list);
-
   if (res)
     DBUG_RETURN(res);
 
@@ -1897,7 +1896,7 @@ pthread_handler_t handle_delayed_insert(
   pthread_detach_this_thread();
   /* Add thread to THD list so that's it's visible in 'show processlist' */
   pthread_mutex_lock(&LOCK_thread_count);
-  thd->thread_id=thread_id++;
+  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
   thd->end_time();
   threads.append(thd);
   thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED;
@@ -1928,14 +1927,8 @@ pthread_handler_t handle_delayed_insert(
     strmov(thd->net.last_error,ER(thd->net.last_errno=ER_OUT_OF_RESOURCES));
     goto err;
   }
-#if !defined(__WIN__) && !defined(__NETWARE__)
-  sigset_t set;
-  VOID(sigemptyset(&set));			// Get mask in use
-  VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
-#endif
 
   /* open table */
-
   if (!(di->table=open_ltable(thd,&di->table_list,TL_WRITE_DELAYED)))
   {
     thd->fatal_error();				// Abort waiting inserts
@@ -2477,7 +2470,6 @@ select_insert::prepare(List<Item> &value
 
   if (info.handle_duplicates == DUP_UPDATE)
   {
-    /* Save the state of the current name resolution context. */
     Name_resolution_context *context= &lex->select_lex.context;
     Name_resolution_context_state ctx_state;
 
@@ -2493,18 +2485,40 @@ select_insert::prepare(List<Item> &value
                                     *info.update_fields, &map);
     lex->select_lex.no_wrap_view_item= FALSE;
     /*
-      When we are not using GROUP BY we can refer to other tables in the
-      ON DUPLICATE KEY part
-    */       
-    if (lex->select_lex.group_list.elements == 0)
-    {
-      context->table_list->next_local=       ctx_state.save_next_local;
-      /* first_name_resolution_table was set by resolve_in_table_list_only() */
-      context->first_name_resolution_table->
-        next_name_resolution_table=          ctx_state.save_next_local;
+      When we are not using GROUP BY and there are no ungrouped aggregate functions 
+      we can refer to other tables in the ON DUPLICATE KEY part.
+      We use next_name_resolution_table descructively, so check it first (views?)
+    */
+    DBUG_ASSERT (!table_list->next_name_resolution_table);
+    if (lex->select_lex.group_list.elements == 0 &&
+        !lex->select_lex.with_sum_func)
+      /*
+        We must make a single context out of the two separate name resolution contexts :
+        the INSERT table and the tables in the SELECT part of INSERT ... SELECT.
+        To do that we must concatenate the two lists
+      */  
+      table_list->next_name_resolution_table= 
+        ctx_state.get_first_name_resolution_table();
+
+    res= res || setup_fields(thd, 0, *info.update_values,
+                             MARK_COLUMNS_READ, 0, 0);
+    if (!res)
+    {
+      /*
+        Traverse the update values list and substitute fields from the
+        select for references (Item_ref objects) to them. This is done in
+        order to get correct values from those fields when the select
+        employs a temporary table.
+      */
+      List_iterator<Item> li(*info.update_values);
+      Item *item;
+
+      while ((item= li++))
+      {
+        item->transform(&Item::update_value_transformer,
+                        (byte*)lex->current_select);
+      }
     }
-    res= res || setup_fields(thd, 0, *info.update_values, MARK_COLUMNS_READ,
-                             0, 0);
 
     /* Restore the current context. */
     ctx_state.restore_state(context, table_list);

--- 1.627/sql/sql_parse.cc	2007-02-21 22:20:15 +04:00
+++ 1.628/sql/sql_parse.cc	2007-02-28 18:48:11 +04:00
@@ -28,24 +28,6 @@
 #include "events.h"
 #include "event_data_objects.h"
 
-#ifdef HAVE_OPENSSL
-/*
-  Without SSL the handshake consists of one packet. This packet
-  has both client capabilites and scrambled password.
-  With SSL the handshake might consist of two packets. If the first
-  packet (client capabilities) has CLIENT_SSL flag set, we have to
-  switch to SSL and read the second packet. The scrambled password
-  is in the second packet and client_capabilites field will be ignored.
-  Maybe it is better to accept flags other than CLIENT_SSL from the
-  second packet?
-*/
-#define SSL_HANDSHAKE_SIZE      2
-#define NORMAL_HANDSHAKE_SIZE   6
-#define MIN_HANDSHAKE_SIZE      2
-#else
-#define MIN_HANDSHAKE_SIZE      6
-#endif /* HAVE_OPENSSL */
-
 /* Used in error handling only */
 #define SP_TYPE_STRING(LP) \
   ((LP)->sphead->m_type == TYPE_ENUM_FUNCTION ? "FUNCTION" : "PROCEDURE")
@@ -56,11 +38,6 @@
    (LP)->sql_command == SQLCOM_DROP_FUNCTION ? \
    "FUNCTION" : "PROCEDURE")
 
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-static void time_out_user_resource_limits(THD *thd, USER_CONN *uc);
-static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
-static void decrease_user_connections(USER_CONN *uc);
-#endif /* NO_EMBEDDED_ACCESS_CHECKS */
 static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
 
 const char *any_db="*any*";	// Special symbol for check_access
@@ -103,20 +80,6 @@ const char *xa_state_names[]={
   "NON-EXISTING", "ACTIVE", "IDLE", "PREPARED"
 };
 
-#ifdef __WIN__
-static void  test_signal(int sig_ptr)
-{
-#if !defined( DBUG_OFF)
-  MessageBox(NULL,"Test signal","DBUG",MB_OK);
-#endif
-}
-static void init_signals(void)
-{
-  int signals[7] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGBREAK,SIGABRT } ;
-  for (int i=0 ; i < 7 ; i++)
-    signal( signals[i], test_signal) ;
-}
-#endif
 
 static void unlock_locked_tables(THD *thd)
 {
@@ -160,6 +123,7 @@ bool end_active_trans(THD *thd)
   DBUG_RETURN(error);
 }
 
+
 bool begin_trans(THD *thd)
 {
   int error=0;
@@ -211,413 +175,6 @@ static bool some_non_temp_table_to_be_up
   return 0;
 }
 
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-static HASH hash_user_connections;
-
-static int get_or_create_user_conn(THD *thd, const char *user,
-				   const char *host,
-				   USER_RESOURCES *mqh)
-{
-  int return_val= 0;
-  uint temp_len, user_len;
-  char temp_user[USER_HOST_BUFF_SIZE];
-  struct  user_conn *uc;
-
-  DBUG_ASSERT(user != 0);
-  DBUG_ASSERT(host != 0);
-
-  user_len= strlen(user);
-  temp_len= (strmov(strmov(temp_user, user)+1, host) - temp_user)+1;
-  (void) pthread_mutex_lock(&LOCK_user_conn);
-  if (!(uc = (struct  user_conn *) hash_search(&hash_user_connections,
-					       (byte*) temp_user, temp_len)))
-  {
-    /* First connection for user; Create a user connection object */
-    if (!(uc= ((struct user_conn*)
-	       my_malloc(sizeof(struct user_conn) + temp_len+1,
-			 MYF(MY_WME)))))
-    {
-      net_send_error(thd, 0, NullS);		// Out of memory
-      return_val= 1;
-      goto end;
-    }
-    uc->user=(char*) (uc+1);
-    memcpy(uc->user,temp_user,temp_len+1);
-    uc->host= uc->user + user_len +  1;
-    uc->len= temp_len;
-    uc->connections= uc->questions= uc->updates= uc->conn_per_hour= 0;
-    uc->user_resources= *mqh;
-    uc->intime= thd->thr_create_time;
-    if (my_hash_insert(&hash_user_connections, (byte*) uc))
-    {
-      my_free((char*) uc,0);
-      net_send_error(thd, 0, NullS);		// Out of memory
-      return_val= 1;
-      goto end;
-    }
-  }
-  thd->user_connect=uc;
-  uc->connections++;
-end:
-  (void) pthread_mutex_unlock(&LOCK_user_conn);
-  return return_val;
-
-}
-#endif /* !NO_EMBEDDED_ACCESS_CHECKS */
-
-
-/*
-  Check if user exist and password supplied is correct. 
-
-  SYNOPSIS
-    check_user()
-    thd          thread handle, thd->security_ctx->{host,user,ip} are used
-    command      originator of the check: now check_user is called
-                 during connect and change user procedures; used for 
-                 logging.
-    passwd       scrambled password received from client
-    passwd_len   length of scrambled password
-    db           database name to connect to, may be NULL
-    check_count  dont know exactly
-
-    Note, that host, user and passwd may point to communication buffer.
-    Current implementation does not depend on that, but future changes
-    should be done with this in mind; 'thd' is INOUT, all other params
-    are 'IN'.
-
-  RETURN VALUE
-    0  OK; thd->security_ctx->user/master_access/priv_user/db_access and
-       thd->db are updated; OK is sent to client;
-   -1  access denied or handshake error; error is sent to client;
-   >0  error, not sent to client
-*/
-
-int check_user(THD *thd, enum enum_server_command command, 
-	       const char *passwd, uint passwd_len, const char *db,
-	       bool check_count)
-{
-  DBUG_ENTER("check_user");
-  
-#ifdef NO_EMBEDDED_ACCESS_CHECKS
-  thd->main_security_ctx.master_access= GLOBAL_ACLS;       // Full rights
-  /* Change database if necessary */
-  if (db && db[0])
-  {
-    /*
-      thd->db is saved in caller and needs to be freed by caller if this
-      function returns 0
-    */
-    thd->reset_db(NULL, 0);
-    if (mysql_change_db(thd, db, FALSE))
-    {
-      /* Send the error to the client */
-      net_send_error(thd);
-      DBUG_RETURN(-1);
-    }
-  }
-  send_ok(thd);
-  DBUG_RETURN(0);
-#else
-
-  my_bool opt_secure_auth_local;
-  pthread_mutex_lock(&LOCK_global_system_variables);
-  opt_secure_auth_local= opt_secure_auth;
-  pthread_mutex_unlock(&LOCK_global_system_variables);
-  
-  /*
-    If the server is running in secure auth mode, short scrambles are 
-    forbidden.
-  */
-  if (opt_secure_auth_local && passwd_len == SCRAMBLE_LENGTH_323)
-  {
-    net_printf_error(thd, ER_NOT_SUPPORTED_AUTH_MODE);
-    general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
-    DBUG_RETURN(-1);
-  }
-  if (passwd_len != 0 &&
-      passwd_len != SCRAMBLE_LENGTH &&
-      passwd_len != SCRAMBLE_LENGTH_323)
-    DBUG_RETURN(ER_HANDSHAKE_ERROR);
-
-  /*
-    Clear thd->db as it points to something, that will be freed when 
-    connection is closed. We don't want to accidentally free a wrong pointer
-    if connect failed. Also in case of 'CHANGE USER' failure, current
-    database will be switched to 'no database selected'.
-  */
-  thd->reset_db(NULL, 0);
-
-  USER_RESOURCES ur;
-  int res= acl_getroot(thd, &ur, passwd, passwd_len);
-#ifndef EMBEDDED_LIBRARY
-  if (res == -1)
-  {
-    /*
-      This happens when client (new) sends password scrambled with
-      scramble(), but database holds old value (scrambled with
-      scramble_323()). Here we please client to send scrambled_password
-      in old format.
-    */
-    NET *net= &thd->net;
-    if (opt_secure_auth_local)
-    {
-      net_printf_error(thd, ER_SERVER_IS_IN_SECURE_AUTH_MODE,
-                       thd->main_security_ctx.user,
-                       thd->main_security_ctx.host_or_ip);
-      general_log_print(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE),
-                        thd->main_security_ctx.user,
-                        thd->main_security_ctx.host_or_ip);
-      DBUG_RETURN(-1);
-    }
-    /* We have to read very specific packet size */
-    if (send_old_password_request(thd) ||
-        my_net_read(net) != SCRAMBLE_LENGTH_323 + 1)
-    {
-      inc_host_errors(&thd->remote.sin_addr);
-      DBUG_RETURN(ER_HANDSHAKE_ERROR);
-    }
-    /* Final attempt to check the user based on reply */
-    /* So as passwd is short, errcode is always >= 0 */
-    res= acl_getroot(thd, &ur, (char *) net->read_pos, SCRAMBLE_LENGTH_323);
-  }
-#endif /*EMBEDDED_LIBRARY*/
-  /* here res is always >= 0 */
-  if (res == 0)
-  {
-    if (!(thd->main_security_ctx.master_access &
-          NO_ACCESS)) // authentication is OK
-    {
-      DBUG_PRINT("info",
-                 ("Capabilities: %lu  packet_length: %ld  Host: '%s'  "
-                  "Login user: '%s' Priv_user: '%s'  Using password: %s "
-                  "Access: %lu  db: '%s'",
-                  thd->client_capabilities,
-                  thd->max_client_packet_length,
-                  thd->main_security_ctx.host_or_ip,
-                  thd->main_security_ctx.user,
-                  thd->main_security_ctx.priv_user,
-                  passwd_len ? "yes": "no",
-                  thd->main_security_ctx.master_access,
-                  (thd->db ? thd->db : "*none*")));
-
-      if (check_count)
-      {
-        VOID(pthread_mutex_lock(&LOCK_thread_count));
-        bool count_ok= thread_count <= max_connections + delayed_insert_threads
-                       || (thd->main_security_ctx.master_access & SUPER_ACL);
-        VOID(pthread_mutex_unlock(&LOCK_thread_count));
-        if (!count_ok)
-        {                                         // too many connections
-          net_send_error(thd, ER_CON_COUNT_ERROR);
-          DBUG_RETURN(-1);
-        }
-      }
-
-      /*
-        Log the command before authentication checks, so that the user can
-        check the log for the tried login tried and also to detect
-        break-in attempts.
-      */
-      general_log_print(thd, command,
-                        (thd->main_security_ctx.priv_user ==
-                         thd->main_security_ctx.user ?
-                         (char*) "%s@%s on %s" :
-                         (char*) "%s@%s as anonymous on %s"),
-                        thd->main_security_ctx.user,
-                        thd->main_security_ctx.host_or_ip,
-                        db ? db : (char*) "");
-
-      /*
-        This is the default access rights for the current database.  It's
-        set to 0 here because we don't have an active database yet (and we
-        may not have an active database to set.
-      */
-      thd->main_security_ctx.db_access=0;
-
-      /* Don't allow user to connect if he has done too many queries */
-      if ((ur.questions || ur.updates || ur.conn_per_hour || ur.user_conn ||
-	   max_user_connections) &&
-	  get_or_create_user_conn(thd,
-            (opt_old_style_user_limits ? thd->main_security_ctx.user :
-             thd->main_security_ctx.priv_user),
-            (opt_old_style_user_limits ? thd->main_security_ctx.host_or_ip :
-             thd->main_security_ctx.priv_host),
-            &ur))
-	DBUG_RETURN(-1);
-      if (thd->user_connect &&
-	  (thd->user_connect->user_resources.conn_per_hour ||
-	   thd->user_connect->user_resources.user_conn ||
-	   max_user_connections) &&
-	  check_for_max_user_connections(thd, thd->user_connect))
-	DBUG_RETURN(-1);
-
-      /* Change database if necessary */
-      if (db && db[0])
-      {
-        if (mysql_change_db(thd, db, FALSE))
-        {
-          /* Send error to the client */
-          net_send_error(thd);
-          if (thd->user_connect)
-            decrease_user_connections(thd->user_connect);
-          DBUG_RETURN(-1);
-        }
-      }
-      send_ok(thd);
-      thd->password= test(passwd_len);          // remember for error messages 
-      /* Ready to handle queries */
-      DBUG_RETURN(0);
-    }
-  }
-  else if (res == 2) // client gave short hash, server has long hash
-  {
-    net_printf_error(thd, ER_NOT_SUPPORTED_AUTH_MODE);
-    general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
-    DBUG_RETURN(-1);
-  }
-  net_printf_error(thd, ER_ACCESS_DENIED_ERROR,
-                   thd->main_security_ctx.user,
-                   thd->main_security_ctx.host_or_ip,
-                   passwd_len ? ER(ER_YES) : ER(ER_NO));
-  general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
-                    thd->main_security_ctx.user,
-                    thd->main_security_ctx.host_or_ip,
-                    passwd_len ? ER(ER_YES) : ER(ER_NO));
-  DBUG_RETURN(-1);
-#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-}
-
-/*
-  Check for maximum allowable user connections, if the mysqld server is
-  started with corresponding variable that is greater then 0.
-*/
-
-extern "C" byte *get_key_conn(user_conn *buff, uint *length,
-			      my_bool not_used __attribute__((unused)))
-{
-  *length=buff->len;
-  return (byte*) buff->user;
-}
-
-extern "C" void free_user(struct user_conn *uc)
-{
-  my_free((char*) uc,MYF(0));
-}
-
-void init_max_user_conn(void)
-{
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-  (void) hash_init(&hash_user_connections,system_charset_info,max_connections,
-		   0,0,
-		   (hash_get_key) get_key_conn, (hash_free_key) free_user,
-		   0);
-#endif
-}
-
-
-/*
-  check if user has already too many connections
-  
-  SYNOPSIS
-  check_for_max_user_connections()
-  thd			Thread handle
-  uc			User connect object
-
-  NOTES
-    If check fails, we decrease user connection count, which means one
-    shouldn't call decrease_user_connections() after this function.
-
-  RETURN
-    0	ok
-    1	error
-*/
-
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-
-static int check_for_max_user_connections(THD *thd, USER_CONN *uc)
-{
-  int error=0;
-  DBUG_ENTER("check_for_max_user_connections");
-
-  (void) pthread_mutex_lock(&LOCK_user_conn);
-  if (max_user_connections && !uc->user_resources.user_conn &&
-      max_user_connections < (uint) uc->connections)
-  {
-    net_printf_error(thd, ER_TOO_MANY_USER_CONNECTIONS, uc->user);
-    error=1;
-    goto end;
-  }
-  time_out_user_resource_limits(thd, uc);
-  if (uc->user_resources.user_conn &&
-      uc->user_resources.user_conn < uc->connections)
-  {
-    net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user,
-                     "max_user_connections",
-                     (long) uc->user_resources.user_conn);
-    error= 1;
-    goto end;
-  }
-  if (uc->user_resources.conn_per_hour &&
-      uc->user_resources.conn_per_hour <= uc->conn_per_hour)
-  {
-    net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user,
-                     "max_connections_per_hour",
-                     (long) uc->user_resources.conn_per_hour);
-    error=1;
-    goto end;
-  }
-  uc->conn_per_hour++;
-
-  end:
-  if (error)
-    uc->connections--; // no need for decrease_user_connections() here
-  (void) pthread_mutex_unlock(&LOCK_user_conn);
-  DBUG_RETURN(error);
-}
-
-/*
-  Decrease user connection count
-
-  SYNOPSIS
-    decrease_user_connections()
-    uc			User connection object
-
-  NOTES
-    If there is a n user connection object for a connection
-    (which only happens if 'max_user_connections' is defined or
-    if someone has created a resource grant for a user), then
-    the connection count is always incremented on connect.
-
-    The user connect object is not freed if some users has
-    'max connections per hour' defined as we need to be able to hold
-    count over the lifetime of the connection.
-*/
-
-static void decrease_user_connections(USER_CONN *uc)
-{
-  DBUG_ENTER("decrease_user_connections");
-  (void) pthread_mutex_lock(&LOCK_user_conn);
-  DBUG_ASSERT(uc->connections);
-  if (!--uc->connections && !mqh_used)
-  {
-    /* Last connection for user; Delete it */
-    (void) hash_delete(&hash_user_connections,(byte*) uc);
-  }
-  (void) pthread_mutex_unlock(&LOCK_user_conn);
-  DBUG_VOID_RETURN;
-}
-
-#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-
-
-void free_max_user_conn(void)
-{
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-  hash_free(&hash_user_connections);
-#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-}
-
-
 
 /*
   Mark all commands that somehow changes a table
@@ -701,402 +258,6 @@ bool is_update_query(enum enum_sql_comma
   return (sql_command_flags[command] & CF_CHANGES_DATA) != 0;
 }
 
-/*
-  Reset per-hour user resource limits when it has been more than
-  an hour since they were last checked
-
-  SYNOPSIS:
-    time_out_user_resource_limits()
-    thd			Thread handler
-    uc			User connection details
-
-  NOTE:
-    This assumes that the LOCK_user_conn mutex has been acquired, so it is
-    safe to test and modify members of the USER_CONN structure.
-*/
-
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-
-static void time_out_user_resource_limits(THD *thd, USER_CONN *uc)
-{
-  time_t check_time = thd->start_time ?  thd->start_time : time(NULL);
-  DBUG_ENTER("time_out_user_resource_limits");
-
-  /* If more than a hour since last check, reset resource checking */
-  if (check_time  - uc->intime >= 3600)
-  {
-    uc->questions=1;
-    uc->updates=0;
-    uc->conn_per_hour=0;
-    uc->intime=check_time;
-  }
-
-  DBUG_VOID_RETURN;
-}
-
-/*
-  Check if maximum queries per hour limit has been reached
-  returns 0 if OK.
-*/
-
-static bool check_mqh(THD *thd, uint check_command)
-{
-  bool error= 0;
-  USER_CONN *uc=thd->user_connect;
-  DBUG_ENTER("check_mqh");
-  DBUG_ASSERT(uc != 0);
-
-  (void) pthread_mutex_lock(&LOCK_user_conn);
-
-  time_out_user_resource_limits(thd, uc);
-
-  /* Check that we have not done too many questions / hour */
-  if (uc->user_resources.questions &&
-      uc->questions++ >= uc->user_resources.questions)
-  {
-    net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, "max_questions",
-                     (long) uc->user_resources.questions);
-    error=1;
-    goto end;
-  }
-  if (check_command < (uint) SQLCOM_END)
-  {
-    /* Check that we have not done too many updates / hour */
-    if (uc->user_resources.updates &&
-        (sql_command_flags[check_command] & CF_CHANGES_DATA) &&
-	uc->updates++ >= uc->user_resources.updates)
-    {
-      net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, "max_updates",
-                       (long) uc->user_resources.updates);
-      error=1;
-      goto end;
-    }
-  }
-end:
-  (void) pthread_mutex_unlock(&LOCK_user_conn);
-  DBUG_RETURN(error);
-}
-
-#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-
-
-static void reset_mqh(LEX_USER *lu, bool get_them= 0)
-{
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-  (void) pthread_mutex_lock(&LOCK_user_conn);
-  if (lu)  // for GRANT
-  {
-    USER_CONN *uc;
-    uint temp_len=lu->user.length+lu->host.length+2;
-    char temp_user[USER_HOST_BUFF_SIZE];
-
-    memcpy(temp_user,lu->user.str,lu->user.length);
-    memcpy(temp_user+lu->user.length+1,lu->host.str,lu->host.length);
-    temp_user[lu->user.length]='\0'; temp_user[temp_len-1]=0;
-    if ((uc = (struct  user_conn *) hash_search(&hash_user_connections,
-						(byte*) temp_user, temp_len)))
-    {
-      uc->questions=0;
-      get_mqh(temp_user,&temp_user[lu->user.length+1],uc);
-      uc->updates=0;
-      uc->conn_per_hour=0;
-    }
-  }
-  else
-  {
-    /* for FLUSH PRIVILEGES and FLUSH USER_RESOURCES */
-    for (uint idx=0;idx < hash_user_connections.records; idx++)
-    {
-      USER_CONN *uc=(struct user_conn *) hash_element(&hash_user_connections,
-						      idx);
-      if (get_them)
-	get_mqh(uc->user,uc->host,uc);
-      uc->questions=0;
-      uc->updates=0;
-      uc->conn_per_hour=0;
-    }
-  }
-  (void) pthread_mutex_unlock(&LOCK_user_conn);
-#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-}
-
-void thd_init_client_charset(THD *thd, uint cs_number)
-{
-  /*
-   Use server character set and collation if
-   - opt_character_set_client_handshake is not set
-   - client has not specified a character set
-   - client character set is the same as the servers
-   - client character set doesn't exists in server
-  */
-  if (!opt_character_set_client_handshake ||
-      !(thd->variables.character_set_client= get_charset(cs_number, MYF(0))) ||
-      !my_strcasecmp(&my_charset_latin1,
-                     global_system_variables.character_set_client->name,
-                     thd->variables.character_set_client->name))
-  {
-    thd->variables.character_set_client=
-      global_system_variables.character_set_client;
-    thd->variables.collation_connection=
-      global_system_variables.collation_connection;
-    thd->variables.character_set_results=
-      global_system_variables.character_set_results;
-  }
-  else
-  {
-    thd->variables.character_set_results=
-      thd->variables.collation_connection= 
-      thd->variables.character_set_client;
-  }
-}
-
-
-/*
-    Perform handshake, authorize client and update thd ACL variables.
-  SYNOPSIS
-    check_connection()
-    thd  thread handle
-
-  RETURN
-     0  success, OK is sent to user, thd is updated.
-    -1  error, which is sent to user
-   > 0  error code (not sent to user)
-*/
-
-#ifndef EMBEDDED_LIBRARY
-static int check_connection(THD *thd)
-{
-  uint connect_errors= 0;
-  NET *net= &thd->net;
-  ulong pkt_len= 0;
-  char *end;
-
-  DBUG_PRINT("info",
-             ("New connection received on %s", vio_description(net->vio)));
-#ifdef SIGNAL_WITH_VIO_CLOSE
-  thd->set_active_vio(net->vio);
-#endif
-
-  if (!thd->main_security_ctx.host)         // If TCP/IP connection
-  {
-    char ip[30];
-
-    if (vio_peer_addr(net->vio, ip, &thd->peer_port))
-      return (ER_BAD_HOST_ERROR);
-    if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(0))))
-      return (ER_OUT_OF_RESOURCES);
-    thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip;
-    vio_in_addr(net->vio,&thd->remote.sin_addr);
-    if (!(specialflag & SPECIAL_NO_RESOLVE))
-    {
-      vio_in_addr(net->vio,&thd->remote.sin_addr);
-      thd->main_security_ctx.host=
-        ip_to_hostname(&thd->remote.sin_addr, &connect_errors);
-      /* Cut very long hostnames to avoid possible overflows */
-      if (thd->main_security_ctx.host)
-      {
-        if (thd->main_security_ctx.host != my_localhost)
-          thd->main_security_ctx.host[min(strlen(thd->main_security_ctx.host),
-                                          HOSTNAME_LENGTH)]= 0;
-        thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
-      }
-      if (connect_errors > max_connect_errors)
-        return(ER_HOST_IS_BLOCKED);
-    }
-    DBUG_PRINT("info",("Host: %s  ip: %s",
-		       (thd->main_security_ctx.host ?
-                        thd->main_security_ctx.host : "unknown host"),
-		       (thd->main_security_ctx.ip ?
-                        thd->main_security_ctx.ip : "unknown ip")));
-    if (acl_check_host(thd->main_security_ctx.host, thd->main_security_ctx.ip))
-      return(ER_HOST_NOT_PRIVILEGED);
-  }
-  else /* Hostname given means that the connection was on a socket */
-  {
-    DBUG_PRINT("info",("Host: %s", thd->main_security_ctx.host));
-    thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
-    thd->main_security_ctx.ip= 0;
-    /* Reset sin_addr */
-    bzero((char*) &thd->remote, sizeof(thd->remote));
-  }
-  vio_keepalive(net->vio, TRUE);
-  {
-    /* buff[] needs to big enough to hold the server_version variable */
-    char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH + 64];
-    ulong client_flags = (CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB |
-			  CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION);
-
-    if (opt_using_transactions)
-      client_flags|=CLIENT_TRANSACTIONS;
-#ifdef HAVE_COMPRESS
-    client_flags |= CLIENT_COMPRESS;
-#endif /* HAVE_COMPRESS */
-#ifdef HAVE_OPENSSL
-    if (ssl_acceptor_fd)
-      client_flags |= CLIENT_SSL;       /* Wow, SSL is available! */
-#endif /* HAVE_OPENSSL */
-
-    end= strnmov(buff, server_version, SERVER_VERSION_LENGTH) + 1;
-    int4store((uchar*) end, thd->thread_id);
-    end+= 4;
-    /*
-      So as check_connection is the only entry point to authorization
-      procedure, scramble is set here. This gives us new scramble for
-      each handshake.
-    */
-    create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
-    /*
-      Old clients does not understand long scrambles, but can ignore packet
-      tail: that's why first part of the scramble is placed here, and second
-      part at the end of packet.
-    */
-    end= strmake(end, thd->scramble, SCRAMBLE_LENGTH_323) + 1;
-   
-    int2store(end, client_flags);
-    /* write server characteristics: up to 16 bytes allowed */
-    end[2]=(char) default_charset_info->number;
-    int2store(end+3, thd->server_status);
-    bzero(end+5, 13);
-    end+= 18;
-    /* write scramble tail */
-    end= strmake(end, thd->scramble + SCRAMBLE_LENGTH_323, 
-                 SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323) + 1;
-
-    /* At this point we write connection message and read reply */
-    if (net_write_command(net, (uchar) protocol_version, "", 0, buff,
-			  (uint) (end-buff)) ||
-	(pkt_len= my_net_read(net)) == packet_error ||
-	pkt_len < MIN_HANDSHAKE_SIZE)
-    {
-      inc_host_errors(&thd->remote.sin_addr);
-      return(ER_HANDSHAKE_ERROR);
-    }
-  }
-#ifdef _CUSTOMCONFIG_
-#include "_cust_sql_parse.h"
-#endif
-  if (connect_errors)
-    reset_host_errors(&thd->remote.sin_addr);
-  if (thd->packet.alloc(thd->variables.net_buffer_length))
-    return(ER_OUT_OF_RESOURCES);
-
-  thd->client_capabilities=uint2korr(net->read_pos);
-  if (thd->client_capabilities & CLIENT_PROTOCOL_41)
-  {
-    thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
-    thd->max_client_packet_length= uint4korr(net->read_pos+4);
-    DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
-    thd_init_client_charset(thd, (uint) net->read_pos[8]);
-    thd->update_charset();
-    end= (char*) net->read_pos+32;
-  }
-  else
-  {
-    thd->max_client_packet_length= uint3korr(net->read_pos+2);
-    end= (char*) net->read_pos+5;
-  }
-
-  if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
-    thd->variables.sql_mode|= MODE_IGNORE_SPACE;
-#ifdef HAVE_OPENSSL
-  DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities));
-  if (thd->client_capabilities & CLIENT_SSL)
-  {
-    /* Do the SSL layering. */
-    if (!ssl_acceptor_fd)
-    {
-      inc_host_errors(&thd->remote.sin_addr);
-      return(ER_HANDSHAKE_ERROR);
-    }
-    DBUG_PRINT("info", ("IO layer change in progress..."));
-    if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout))
-    {
-      DBUG_PRINT("error", ("Failed to accept new SSL connection"));
-      inc_host_errors(&thd->remote.sin_addr);
-      return(ER_HANDSHAKE_ERROR);
-    }
-    DBUG_PRINT("info", ("Reading user information over SSL layer"));
-    if ((pkt_len= my_net_read(net)) == packet_error ||
-	pkt_len < NORMAL_HANDSHAKE_SIZE)
-    {
-      DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
-			   pkt_len));
-      inc_host_errors(&thd->remote.sin_addr);
-      return(ER_HANDSHAKE_ERROR);
-    }
-  }
-#endif
-
-  if (end >= (char*) net->read_pos+ pkt_len +2)
-  {
-    inc_host_errors(&thd->remote.sin_addr);
-    return(ER_HANDSHAKE_ERROR);
-  }
-
-  if (thd->client_capabilities & CLIENT_INTERACTIVE)
-    thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
-  if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
-      opt_using_transactions)
-    net->return_status= &thd->server_status;
-
-  char *user= end;
-  char *passwd= strend(user)+1;
-  uint user_len= passwd - user - 1;
-  char *db= passwd;
-  char db_buff[NAME_LEN + 1];           // buffer to store db in utf8
-  char user_buff[USERNAME_LENGTH + 1];	// buffer to store user in utf8
-  uint dummy_errors;
-
-  /*
-    Old clients send null-terminated string as password; new clients send
-    the size (1 byte) + string (not null-terminated). Hence in case of empty
-    password both send '\0'.
-
-    This strlen() can't be easily deleted without changing protocol.
-  */
-  uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
-    *passwd++ : strlen(passwd);
-  db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
-    db + passwd_len + 1 : 0;
-  /* strlen() can't be easily deleted without changing protocol */
-  uint db_len= db ? strlen(db) : 0;
-
-  if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
-  {
-    inc_host_errors(&thd->remote.sin_addr);
-    return ER_HANDSHAKE_ERROR;
-  }
-
-  /* Since 4.1 all database names are stored in utf8 */
-  if (db)
-  {
-    db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
-                             system_charset_info,
-                             db, db_len,
-                             thd->charset(), &dummy_errors)]= 0;
-    db= db_buff;
-  }
-
-  user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
-                                       system_charset_info, user, user_len,
-                                       thd->charset(), &dummy_errors)]= '\0';
-  user= user_buff;
-
-  /* If username starts and ends in "'", chop them off */
-  if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
-  {
-    user[user_len-1]= 0;
-    user++;
-    user_len-= 2;
-  }
-
-  if (thd->main_security_ctx.user)
-    x_free(thd->main_security_ctx.user);
-  if (!(thd->main_security_ctx.user= my_strdup(user, MYF(0))))
-    return (ER_OUT_OF_RESOURCES);
-  return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE);
-}
-
 
 void execute_init_command(THD *thd, sys_var_str *init_command_var,
 			  rw_lock_t *var_mutex)
@@ -1129,153 +290,6 @@ void execute_init_command(THD *thd, sys_
 }
 
 
-pthread_handler_t handle_one_connection(void *arg)
-{
-  THD *thd=(THD*) arg;
-  uint launch_time  =
-    (uint) ((thd->thr_create_time = time(NULL)) - thd->connect_time);
-  if (launch_time >= slow_launch_time)
-    statistic_increment(slow_launch_threads,&LOCK_status );
-
-  pthread_detach_this_thread();
-
-#if !defined( __WIN__) // Win32 calls this in pthread_create
-  /* The following calls needs to be done before we call DBUG_ macros */
-  if (!(test_flags & TEST_NO_THREADS) & my_thread_init())
-  {
-    close_connection(thd, ER_OUT_OF_RESOURCES, 1);
-    statistic_increment(aborted_connects,&LOCK_status);
-    end_thread(thd,0);
-    return 0;
-  }
-#endif
-
-  /*
-    handle_one_connection() is the only way a thread would start
-    and would always be on top of the stack, therefore, the thread
-    stack always starts at the address of the first local variable
-    of handle_one_connection, which is thd. We need to know the
-    start of the stack so that we could check for stack overruns.
-  */
-  DBUG_PRINT("info", ("handle_one_connection called by thread %lu\n",
-		      thd->thread_id));
-  /* now that we've called my_thread_init(), it is safe to call DBUG_* */
-
-#if defined(__WIN__)
-  init_signals();
-#elif !defined(__NETWARE__)
-  sigset_t set;
-  VOID(sigemptyset(&set));			// Get mask in use
-  VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
-#endif
-  thd->thread_stack= (char*) &thd;
-  if (thd->store_globals())
-  {
-    close_connection(thd, ER_OUT_OF_RESOURCES, 1);
-    statistic_increment(aborted_connects,&LOCK_status);
-    end_thread(thd,0);
-    return 0;
-  }
-
-  do
-  {
-    int error;
-    NET *net= &thd->net;
-    Security_context *sctx= thd->security_ctx;
-    net->no_send_error= 0;
-
-    /* Use "connect_timeout" value during connection phase */
-    net_set_read_timeout(net, connect_timeout);
-    net_set_write_timeout(net, connect_timeout);
-
-    if ((error=check_connection(thd)))
-    {						// Wrong permissions
-      if (error > 0)
-	net_printf_error(thd, error, sctx->host_or_ip);
-#ifdef __NT__
-      if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE)
-	my_sleep(1000);				/* must wait after eof() */
-#endif
-      statistic_increment(aborted_connects,&LOCK_status);
-      goto end_thread;
-    }
-#ifdef __NETWARE__
-    netware_reg_user(sctx->ip, sctx->user, "MySQL");
-#endif
-    if (thd->variables.max_join_size == HA_POS_ERROR)
-      thd->options |= OPTION_BIG_SELECTS;
-    if (thd->client_capabilities & CLIENT_COMPRESS)
-      net->compress=1;				// Use compression
-
-    thd->version= refresh_version;
-    THD_SET_PROC_INFO(thd, 0);
-    thd->command= COM_SLEEP;
-    thd->set_time();
-    thd->init_for_queries();
-
-    if (sys_init_connect.value_length && !(sctx->master_access & SUPER_ACL))
-    {
-      execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect);
-      if (thd->query_error)
-      {
-	thd->killed= THD::KILL_CONNECTION;
-        sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
-                          thd->thread_id,(thd->db ? thd->db : "unconnected"),
-                          sctx->user ? sctx->user : "unauthenticated",
-                          sctx->host_or_ip, "init_connect command failed");
-        sql_print_warning("%s", net->last_error);
-      }
-      THD_SET_PROC_INFO(thd, 0);
-      thd->set_time();
-      thd->init_for_queries();
-    }
-
-    /* Connect completed, set read/write timeouts back to tdefault */
-    net_set_read_timeout(net, thd->variables.net_read_timeout);
-    net_set_write_timeout(net, thd->variables.net_write_timeout);
-
-    while (!net->error && net->vio != 0 &&
-           !(thd->killed == THD::KILL_CONNECTION))
-    {
-      net->no_send_error= 0;
-      if (do_command(thd))
-	break;
-    }
-    if (thd->user_connect)
-      decrease_user_connections(thd->user_connect);
-    if (net->error && net->vio != 0 && net->report_error)
-    {
-      if (!thd->killed && thd->variables.log_warnings > 1)
-	sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
-                          thd->thread_id,(thd->db ? thd->db : "unconnected"),
-                          sctx->user ? sctx->user : "unauthenticated",
-                          sctx->host_or_ip,
-                          (net->last_errno ? ER(net->last_errno) :
-                           ER(ER_UNKNOWN_ERROR)));
-      net_send_error(thd, net->last_errno, NullS);
-      statistic_increment(aborted_threads,&LOCK_status);
-    }
-    else if (thd->killed)
-    {
-      statistic_increment(aborted_threads,&LOCK_status);
-    }
-    
-end_thread:
-    close_connection(thd, 0, 1);
-    end_thread(thd,1);
-    /*
-      If end_thread returns, we are either running with --one-thread
-      or this thread has been schedule to handle the next query
-    */
-    thd= current_thd;
-    thd->thread_stack= (char*) &thd;
-  } while (!(test_flags & TEST_NO_THREADS));
-  /* The following is only executed if we are not using --one-thread */
-  return(0);					/* purecov: deadcode */
-}
-
-#endif /* EMBEDDED_LIBRARY */
-
 /*
   Execute commands from bootstrap_file.
   Used when creating the initial grant tables
@@ -1302,11 +316,6 @@ pthread_handler_t handle_bootstrap(void 
 #ifndef EMBEDDED_LIBRARY
   pthread_detach_this_thread();
   thd->thread_stack= (char*) &thd;
-#if !defined(__WIN__) && !defined(__NETWARE__)
-  sigset_t set;
-  VOID(sigemptyset(&set));			// Get mask in use
-  VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
-#endif
 #endif /* EMBEDDED_LIBRARY */
 
   if (thd->variables.max_join_size == HA_POS_ERROR)
@@ -2085,7 +1094,6 @@ bool dispatch_command(enum enum_server_c
     */
     enum mysql_enum_shutdown_level level=
       (enum mysql_enum_shutdown_level) (uchar) packet[0];
-    DBUG_PRINT("quit",("Got shutdown command for level %u", level));
     if (level == SHUTDOWN_DEFAULT)
       level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable
     else if (level != SHUTDOWN_WAIT_ALL_BUFFERS)
@@ -4230,7 +3238,7 @@ end_with_restore_list:
           {
             if (!(user= get_current_user(thd, tmp_user)))
               goto error;
-	    reset_mqh(user);
+	    reset_mqh(user, 0);
           }
 	}
       }
@@ -4260,7 +3268,9 @@ end_with_restore_list:
         We WANT to write and we CAN write.
         ! we write after unlocking the table.
       */
-      /* Presumably, RESET and binlog writing doesn't require synchronization */
+      /*
+        Presumably, RESET and binlog writing doesn't require synchronization
+      */
       if (!lex->no_write_to_binlog && write_to_binlog)
       {
         if (mysql_bin_log.is_open())
@@ -6580,6 +5590,7 @@ bool st_select_lex::init_nested_join(THD
   join_list->push_front(ptr);
   ptr->embedding= embedding;
   ptr->join_list= join_list;
+  ptr->alias= (char*) "(nested_join)";
   embedding= ptr;
   join_list= &nested_join->join_list;
   join_list->empty();
@@ -6664,6 +5675,7 @@ TABLE_LIST *st_select_lex::nest_last_joi
 
   ptr->embedding= embedding;
   ptr->join_list= join_list;
+  ptr->alias= (char*) "(nest_last_join)";
   embedded_list= &nested_join->join_list;
   embedded_list->empty();
 
@@ -7158,7 +6170,7 @@ bool reload_acl_and_cache(THD *thd, ulon
  }
 #endif
  if (options & REFRESH_USER_RESOURCES)
-   reset_mqh((LEX_USER *) NULL);
+   reset_mqh((LEX_USER *) NULL, 0);		/* purecov: inspected */
  *write_to_binlog= tmp_write_to_binlog;
  return result;
 }

--- 1.493/sql/sql_select.cc	2007-02-21 22:20:16 +04:00
+++ 1.494/sql/sql_select.cc	2007-02-28 18:27:05 +04:00
@@ -268,6 +268,70 @@ bool handle_select(THD *thd, LEX *lex, s
 
 
 /*
+  Fix fields referenced from inner selects.
+
+  SYNOPSIS
+    fix_inner_refs()
+    thd               Thread handle
+    all_fields        List of all fields used in select
+    select            Current select
+    ref_pointer_array Array of references to Items used in current select
+
+  DESCRIPTION
+    The function fixes fields referenced from inner selects and
+    also fixes references (Item_ref objects) to these fields. Each field
+    is fixed as a usual hidden field of the current select - it is added
+    to the all_fields list and the pointer to it is saved in the
+    ref_pointer_array if latter is provided.
+    After the field has been fixed we proceed with fixing references
+    (Item_ref objects) to this field from inner subqueries. If the
+    ref_pointer_array is provided then Item_ref objects is set to
+    reference element in that array with the pointer to the field.
+
+  RETURN
+    TRUE  an error occured
+    FALSE ok
+*/
+
+bool
+fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
+                 Item **ref_pointer_array)
+{
+  Item_outer_ref *ref;
+  bool res= FALSE;
+  List_iterator<Item_outer_ref> ref_it(select->inner_refs_list);
+  while ((ref= ref_it++))
+  {
+    Item_field *item= ref->outer_field;
+    /*
+      TODO: this field item already might be present in the select list.
+      In this case instead of adding new field item we could use an
+      existing one. The change will lead to less operations for copying fields,
+      smaller temporary tables and less data passed through filesort.
+    */
+    if (ref_pointer_array)
+    {
+      int el= all_fields.elements;
+      ref_pointer_array[el]= (Item*)item;
+      /* Add the field item to the select list of the current select. */
+      all_fields.push_front((Item*)item);
+      /*
+        If it's needed reset each Item_ref item that refers this field with
+        a new reference taken from ref_pointer_array.
+      */
+      ref->ref= ref_pointer_array + el;
+    }
+    if (!ref->fixed && ref->fix_fields(thd, 0))
+    {
+      res= TRUE;
+      break;
+    }
+    thd->used_tables|= item->used_tables();
+  }
+  return res;
+}
+
+/*
   Function to setup clauses without sum functions
 */
 inline int setup_without_group(THD *thd, Item **ref_pointer_array,
@@ -394,6 +458,10 @@ JOIN::prepare(Item ***rref_pointer_array
   if (having && having->with_sum_func)
     having->split_sum_func2(thd, ref_pointer_array, all_fields,
                             &having, TRUE);
+  if (select_lex->inner_refs_list.elements &&
+      fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array))
+    DBUG_RETURN(-1);
+
   if (select_lex->inner_sum_func_list)
   {
     Item_sum *end=select_lex->inner_sum_func_list;
@@ -474,6 +542,9 @@ JOIN::prepare(Item ***rref_pointer_array
     }
   }
 
+  if (!procedure && result && result->prepare(fields_list, unit_arg))
+    goto err;					/* purecov: inspected */
+
   /* Init join struct */
   count_field_types(&tmp_table_param, all_fields, 0);
   ref_pointer_array_size= all_fields.elements*sizeof(Item*);
@@ -487,9 +558,6 @@ JOIN::prepare(Item ***rref_pointer_array
     goto err;
   }
 #endif
-  if (!procedure && result && result->prepare(fields_list, unit_arg))
-    goto err;					/* purecov: inspected */
-
   if (select_lex->olap == ROLLUP_TYPE && rollup_init())
     goto err;
   if (alloc_func_list())
@@ -2884,15 +2952,9 @@ add_key_field(KEY_FIELD **key_fields,uin
           /*
             We can't use indexes if the effective collation
             of the operation differ from the field collation.
-
-            We also cannot use index on a text column, as the column may
-            contain 'x' 'x\t' 'x ' and 'read_next_same' will stop after
-            'x' when searching for WHERE col='x '
           */
           if (field->cmp_type() == STRING_RESULT &&
-              (((Field_str*)field)->charset() != cond->compare_collation() ||
-               ((*value)->type() != Item::NULL_ITEM &&
-                (field->flags & BLOB_FLAG) && !field->binary())))
+              ((Field_str*)field)->charset() != cond->compare_collation())
             return;
         }
       }
@@ -5287,13 +5349,15 @@ get_store_key(THD *thd, KEYUSE *keyuse, 
 				    key_part->length,
 				    keyuse->val);
   }
-  else if (keyuse->val->type() == Item::FIELD_ITEM)
+  else if (keyuse->val->type() == Item::FIELD_ITEM ||
+           (keyuse->val->type() == Item::REF_ITEM &&
+            ((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF) )
     return new store_key_field(thd,
 			       key_part->field,
 			       key_buff + maybe_null,
 			       maybe_null ? key_buff : 0,
 			       key_part->length,
-			       ((Item_field*) keyuse->val)->field,
+			       ((Item_field*) keyuse->val->real_item())->field,
 			       keyuse->val->full_name());
   return new store_key_item(thd,
 			    key_part->field,
@@ -8264,7 +8328,7 @@ static uint build_bitmap_for_nested_join
       */
       if (nested_join->join_list.elements != 1)
       {
-        nested_join->nj_map= 1 << first_unused++;
+        nested_join->nj_map= (nested_join_map) 1 << first_unused++;
         first_unused= build_bitmap_for_nested_joins(&nested_join->join_list,
                                                     first_unused);
       }
@@ -8887,7 +8951,8 @@ static Field *create_tmp_field_from_item
       type they needed to be handled separately.
     */
     if ((type= item->field_type()) == MYSQL_TYPE_DATETIME ||
-        type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE)
+        type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE ||
+        type == MYSQL_TYPE_TIMESTAMP)
       new_field= item->tmp_table_field_from_field_type(table, 1);
     /* 
       Make sure that the blob fits into a Field_varstring which has 
@@ -9003,8 +9068,7 @@ Field *create_tmp_field(THD *thd, TABLE 
   Item *orig_item= 0;
 
   if (type != Item::FIELD_ITEM &&
-      item->real_item()->type() == Item::FIELD_ITEM &&
-      !((Item_ref *) item)->depended_from)
+      item->real_item()->type() == Item::FIELD_ITEM)
   {
     orig_item= item;
     item= item->real_item();
@@ -9166,7 +9230,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARA
   uint  hidden_null_count, hidden_null_pack_length, hidden_field_count;
   uint  blob_count,group_null_items, string_count;
   uint  temp_pool_slot=MY_BIT_NONE;
-  ulong reclength, string_total_length, fieldnr= 0;
+  uint fieldnr= 0;
+  ulong reclength, string_total_length;
   bool  using_unique_constraint= 0;
   bool  use_packed_rows= 0;
   bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
@@ -10336,7 +10401,6 @@ do_select(JOIN *join,List<Item> *fields,
   else
   {
     DBUG_ASSERT(join->tables);
-    DBUG_ASSERT(join_tab);
     error= sub_select(join,join_tab,0);
     if (error == NESTED_LOOP_OK || error == NESTED_LOOP_NO_MORE_ROWS)
       error= sub_select(join,join_tab,1);
@@ -13723,10 +13787,8 @@ count_field_types(TMP_TABLE_PARAM *param
   param->quick_group=1;
   while ((field=li++))
   {
-    Item::Type type=field->type();
     Item::Type real_type= field->real_item()->type();
-    if (type == Item::FIELD_ITEM || (real_type == Item::FIELD_ITEM &&
-        !((Item_ref *) field)->depended_from))
+    if (real_type == Item::FIELD_ITEM)
       param->field_count++;
     else if (real_type == Item::SUM_FUNC_ITEM)
     {
@@ -15200,7 +15262,8 @@ static void select_describe(JOIN *join, 
         Item_float *filtered;
         float f; 
         if (examined_rows)
-          f= 100.0 * join->best_positions[i].records_read / examined_rows;
+          f= (float) (100.0 * join->best_positions[i].records_read /
+                      examined_rows);
         else
           f= 0.0;
         item_list.push_back((filtered= new Item_float(f)));

--- 1.389/sql/sql_table.cc	2007-02-21 22:20:17 +04:00
+++ 1.390/sql/sql_table.cc	2007-02-28 18:27:05 +04:00
@@ -41,7 +41,7 @@ static int copy_data_between_tables(TABL
 
 static bool prepare_blob_field(THD *thd, create_field *sql_field);
 static bool check_engine(THD *thd, const char *table_name,
-                         HA_CREATE_INFO *create_info);                             
+                         HA_CREATE_INFO *create_info);
 static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
                                List<create_field> *fields,
                                List<Key> *keys, bool tmp_table,
@@ -460,10 +460,10 @@ static bool write_ddl_log_header()
             global_ddl_log.num_entries);
   const_var= FN_LEN;
   int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_LEN_POS],
-            const_var);
+            (ulong) const_var);
   const_var= IO_SIZE;
   int4store(&global_ddl_log.file_entry_buf[DDL_LOG_IO_SIZE_POS],
-            const_var);
+            (ulong) const_var);
   if (write_ddl_log_file_entry(0UL))
   {
     sql_print_error("Error writing ddl log header");
@@ -3416,16 +3416,11 @@ bool mysql_create_table_internal(THD *th
   {
  #ifdef FN_DEVCHAR
     /* check if the table name contains FN_DEVCHAR when defined */
-    const char *start= alias;
-    while (*start != '\0')
+    if (strchr(alias, FN_DEVCHAR))
     {
-      if (*start == FN_DEVCHAR)
-      {
-        my_error(ER_WRONG_TABLE_NAME, MYF(0), alias);
-        DBUG_RETURN(TRUE);
-      }
-      start++;
-    }	  
+      my_error(ER_WRONG_TABLE_NAME, MYF(0), alias);
+      DBUG_RETURN(TRUE);
+    }
 #endif
     path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
                                       internal_tmp_table ? FN_IS_TMP : 0);
@@ -4602,7 +4597,7 @@ bool mysql_create_like_table(THD* thd, T
                              Table_ident *table_ident)
 {
   TABLE *tmp_table;
-  char src_path[FN_REFLEN], dst_path[FN_REFLEN], tmp_path[FN_REFLEN];
+  char src_path[FN_REFLEN], dst_path[FN_REFLEN];
   char src_table_name_buff[FN_REFLEN], src_db_name_buff[FN_REFLEN];
   uint dst_path_length;
   char *db= table->db;
@@ -4613,7 +4608,9 @@ bool mysql_create_like_table(THD* thd, T
   bool res= TRUE, unlock_dst_table= FALSE;
   enum legacy_db_type not_used;
   HA_CREATE_INFO *create_info;
-
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+  char tmp_path[FN_REFLEN];
+#endif
   TABLE_LIST src_tables_list, dst_tables_list;
   DBUG_ENTER("mysql_create_like_table");
 
@@ -4821,7 +4818,8 @@ bool mysql_create_like_table(THD* thd, T
         else
           unlock_dst_table= TRUE;
 
-        int result= store_create_info(thd, table, &query, create_info);
+        IF_DBUG(int result=) store_create_info(thd, table, &query,
+                                               create_info);
 
         DBUG_ASSERT(result == 0); // store_create_info() always return 0
         write_bin_log(thd, TRUE, query.ptr(), query.length());
@@ -6648,7 +6646,8 @@ view_err:
                       thd->query, thd->query_length,
                       db, table_name);
 
-  DBUG_ASSERT(!(mysql_bin_log.is_open() && thd->current_stmt_binlog_row_based &&
+  DBUG_ASSERT(!(mysql_bin_log.is_open() &&
+                thd->current_stmt_binlog_row_based &&
                 (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
   write_bin_log(thd, TRUE, thd->query, thd->query_length);
 

--- 1.217/sql/sql_update.cc	2007-02-21 22:20:17 +04:00
+++ 1.218/sql/sql_update.cc	2007-02-28 18:27:05 +04:00
@@ -133,6 +133,7 @@ int mysql_update(THD *thd,
   SELECT_LEX    *select_lex= &thd->lex->select_lex;
   bool          need_reopen;
   ulonglong     id;
+  List<Item> all_fields;
   DBUG_ENTER("mysql_update");
 
   for ( ; ; )
@@ -215,6 +216,10 @@ int mysql_update(THD *thd,
     free_underlaid_joins(thd, select_lex);
     DBUG_RETURN(1);				/* purecov: inspected */
   }
+
+  if (select_lex->inner_refs_list.elements &&
+    fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
+    DBUG_RETURN(-1);
 
   if (conds)
   {

--- 1.476/sql/sql_yacc.yy	2007-02-21 22:20:18 +04:00
+++ 1.477/sql/sql_yacc.yy	2007-02-28 18:27:06 +04:00
@@ -556,7 +556,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  GLOBAL_SYM                    /* SQL-2003-R */
 %token  GRANT                         /* SQL-2003-R */
 %token  GRANTS
-%token  GROUP                         /* SQL-2003-R */
+%token  GROUP_SYM                     /* SQL-2003-R */
 %token  GROUP_CONCAT_SYM
 %token  GT_SYM                        /* OPERATOR */
 %token  HANDLER_SYM
@@ -1505,7 +1505,7 @@ create:
 	  {
 	    Lex->sql_command = SQLCOM_CREATE_USER;
           }
-	| CREATE LOGFILE_SYM GROUP logfile_group_info 
+	| CREATE LOGFILE_SYM GROUP_SYM logfile_group_info 
           {
             Lex->alter_tablespace_info->ts_cmd_type= CREATE_LOGFILE_GROUP;
           }
@@ -3081,11 +3081,11 @@ trg_event:
   ALTER TABLESPACE name CHANGE DATAFILE ...
   ALTER TABLESPACE name ADD DATAFILE ...
   ALTER TABLESPACE name access_mode
-  CREATE LOGFILE GROUP name ...
-  ALTER LOGFILE GROUP name ADD UNDOFILE ..
-  ALTER LOGFILE GROUP name ADD REDOFILE ..
+  CREATE LOGFILE GROUP_SYM name ...
+  ALTER LOGFILE GROUP_SYM name ADD UNDOFILE ..
+  ALTER LOGFILE GROUP_SYM name ADD REDOFILE ..
   DROP TABLESPACE name
-  DROP LOGFILE GROUP name
+  DROP LOGFILE GROUP_SYM name
 */
 change_tablespace_access:
           tablespace_name
@@ -3107,7 +3107,7 @@ tablespace_info:
 
 opt_logfile_group_name:
           /* empty */ {}
-          | USE_SYM LOGFILE_SYM GROUP ident
+          | USE_SYM LOGFILE_SYM GROUP_SYM ident
           {
             LEX *lex= Lex;
             lex->alter_tablespace_info->logfile_group_name= $4.str;
@@ -5073,7 +5073,7 @@ alter:
             LEX *lex= Lex;
             lex->alter_tablespace_info->ts_cmd_type= ALTER_TABLESPACE;
           }
-        | ALTER LOGFILE_SYM GROUP alter_logfile_group_info
+        | ALTER LOGFILE_SYM GROUP_SYM alter_logfile_group_info
           {
             LEX *lex= Lex;
             lex->alter_tablespace_info->ts_cmd_type= ALTER_LOGFILE_GROUP;
@@ -5941,8 +5941,13 @@ select_into:
 	| select_from into;
 
 select_from:
-	  FROM join_table_list where_clause group_clause having_clause
+        FROM join_table_list where_clause group_clause having_clause
 	       opt_order_clause opt_limit_clause procedure_clause
+          {
+            Select->context.table_list=
+              Select->context.first_name_resolution_table= 
+                (TABLE_LIST *) Select->table_list.first;
+          }
         | FROM DUAL_SYM where_clause opt_limit_clause
           /* oracle compatibility: oracle always requires FROM clause,
              and DUAL is system table without fields.
@@ -7552,7 +7557,7 @@ opt_escape:
 
 group_clause:
 	/* empty */
-	| GROUP BY group_list olap_opt;
+	| GROUP_SYM BY group_list olap_opt;
 
 group_list:
 	group_list ',' order_ident order_dir
@@ -8016,7 +8021,7 @@ drop:
             LEX *lex= Lex;
             lex->alter_tablespace_info->ts_cmd_type= DROP_TABLESPACE;
           }
-        | DROP LOGFILE_SYM GROUP logfile_group_name opt_ts_engine opt_ts_wait
+        | DROP LOGFILE_SYM GROUP_SYM logfile_group_name opt_ts_engine opt_ts_wait
           {
             LEX *lex= Lex;
             lex->alter_tablespace_info->ts_cmd_type= DROP_LOGFILE_GROUP;
@@ -11045,6 +11050,12 @@ subselect_end:
 	  lex->current_select = lex->current_select->return_after_parsing();
           lex->nest_level--;
           lex->current_select->n_child_sum_items += child->n_sum_items;
+          /*
+            A subselect can add fields to an outer select. Reserve space for
+            them.
+          */
+          lex->current_select->select_n_where_fields+=
+            child->select_n_where_fields;
 	};
 
 /**************************************************************************

--- 1.30/sql/event_scheduler.cc	2007-02-21 22:20:12 +04:00
+++ 1.31/sql/event_scheduler.cc	2007-02-28 18:27:03 +04:00
@@ -104,25 +104,22 @@ evex_print_warnings(THD *thd, Event_job_
   SYNOPSIS
     post_init_event_thread()
       thd  Thread
+
+  NOTES
+    Before this is called, one should not do any DBUG_XXX() calls.
+
 */
 
 bool
 post_init_event_thread(THD *thd)
 {
-  my_thread_init();
-  pthread_detach_this_thread();
-  thd->real_id= pthread_self();
+  (void) init_new_connection_handler_thread();
   if (init_thr_lock() || thd->store_globals())
   {
     thd->cleanup();
     return TRUE;
   }
 
-#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
-  sigset_t set;
-    VOID(sigemptyset(&set));                    // Get mask in use
-  VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
-#endif
   pthread_mutex_lock(&LOCK_thread_count);
   threads.append(thd);
   thread_count++;
@@ -187,7 +184,7 @@ pre_init_event_thread(THD* thd)
   thd->options|= OPTION_AUTO_IS_NULL;
   thd->client_capabilities|= CLIENT_MULTI_RESULTS;
   pthread_mutex_lock(&LOCK_thread_count);
-  thd->thread_id= thread_id++;
+  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
   pthread_mutex_unlock(&LOCK_thread_count);
 
   /*
@@ -218,20 +215,20 @@ pthread_handler_t
 event_scheduler_thread(void *arg)
 {
   /* needs to be first for thread_stack */
-  THD *thd= (THD *)((struct scheduler_param *) arg)->thd;
+  THD *thd= (THD *) ((struct scheduler_param *) arg)->thd;
   Event_scheduler *scheduler= ((struct scheduler_param *) arg)->scheduler;
+  bool res;
 
-  my_free((char*)arg, MYF(0));
-
-  thd->thread_stack= (char *)&thd;              // remember where our stack is
+  thd->thread_stack= (char*) &thd;              // remember where our stack is
+  res= post_init_event_thread(thd);
 
   DBUG_ENTER("event_scheduler_thread");
-
-  if (!post_init_event_thread(thd))
+  my_free((char*)arg, MYF(0));
+  if (!res)
     scheduler->run(thd);
 
   deinit_event_thread(thd);
-
+  pthread_exit(0);
   DBUG_RETURN(0);                               // Against gcc warnings
 }
 
@@ -255,13 +252,14 @@ event_worker_thread(void *arg)
   THD *thd; 
   Event_job_data *event= (Event_job_data *)arg;
   int ret;
+  bool res;
 
   thd= event->thd;
-
   thd->thread_stack= (char *) &thd;             // remember where our stack is
+  res= post_init_event_thread(thd);
   DBUG_ENTER("event_worker_thread");
 
-  if (!post_init_event_thread(thd))
+  if (!res)
   {
     DBUG_PRINT("info", ("Baikonur, time is %ld, BURAN reporting and operational."
                         "THD: 0x%lx",
@@ -295,6 +293,7 @@ event_worker_thread(void *arg)
 
   deinit_event_thread(thd);
 
+  pthread_exit(0);
   DBUG_RETURN(0);                               // Can't return anything here
 }
 

--- 1.118/sql/sql_view.cc	2007-02-21 22:20:17 +04:00
+++ 1.119/sql/sql_view.cc	2007-02-28 18:27:06 +04:00
@@ -713,7 +713,7 @@ static int mysql_register_view(THD *thd,
     File_parser *parser;
 
     path.str= path_buff;
-    fn_format(path_buff, file.str, dir.str, 0, MY_UNPACK_FILENAME);
+    fn_format(path_buff, file.str, dir.str, "", MY_UNPACK_FILENAME);
     path.length= strlen(path_buff);
 
     if (!access(path.str, F_OK))

--- 1.131/mysql-test/mysql-test-run.pl	2007-02-21 22:20:11 +04:00
+++ 1.132/mysql-test/mysql-test-run.pl	2007-02-28 18:27:03 +04:00
@@ -409,24 +409,24 @@ sub main () {
     {
       next if $test->{skip};
 
-      $need_ndbcluster||= $test->{ndb_test};
-      $need_im||= $test->{component_id} eq 'im';
-
-      # Count max number of slaves used by a test case
-      if ( $test->{slave_num} > $max_slave_num)
+      if (!$opt_extern)
       {
-	$max_slave_num= $test->{slave_num};
-	mtr_error("Too many slaves") if $max_slave_num > 3;
-      }
+	$need_ndbcluster||= $test->{ndb_test};
+	$need_im||= $test->{component_id} eq 'im';
 
-      # Count max number of masters used by a test case
-      if ( $test->{master_num} > $max_master_num)
-      {
-	$max_master_num= $test->{master_num};
-	mtr_error("Too many masters") if $max_master_num > 2;
-	mtr_error("Too few masters") if $max_master_num < 1;
-      }
+	# Count max number of slaves used by a test case
+	if ( $test->{slave_num} > $max_slave_num) {
+	  $max_slave_num= $test->{slave_num};
+	  mtr_error("Too many slaves") if $max_slave_num > 3;
+	}
 
+	# Count max number of masters used by a test case
+	if ( $test->{master_num} > $max_master_num) {
+	  $max_master_num= $test->{master_num};
+	  mtr_error("Too many masters") if $max_master_num > 2;
+	  mtr_error("Too few masters") if $max_master_num < 1;
+	}
+      }
       $use_innodb||= $test->{'innodb_test'};
     }
 
@@ -700,7 +700,9 @@ sub command_line_setup () {
 				       "$glob_basedir/client",
 				       "$glob_basedir/bin");
 
-  $exe_mysqld=         mtr_exe_exists (vs_config_dirs('sql', 'mysqld'),
+  if (!$opt_extern)
+  {
+    $exe_mysqld=       mtr_exe_exists (vs_config_dirs('sql', 'mysqld'),
 				       "$glob_basedir/sql/mysqld",
 				       "$path_client_bindir/mysqld-max-nt",
 				       "$path_client_bindir/mysqld-max",
@@ -712,8 +714,16 @@ sub command_line_setup () {
 				       "$glob_basedir/bin/mysqld",
 				       "$glob_basedir/sbin/mysqld");
 
-  # Use the mysqld found above to find out what features are available
-  collect_mysqld_features();
+    # Use the mysqld found above to find out what features are available
+    collect_mysqld_features();
+  }
+  else
+  {
+    $mysqld_variables{'port'}= 3306;
+    $mysqld_variables{'master-port'}= 3306;
+    $opt_skip_ndbcluster= 1;
+    $opt_skip_im= 1;
+  }
 
   if ( $opt_comment )
   {
@@ -750,7 +760,7 @@ sub command_line_setup () {
   # --------------------------------------------------------------------------
   # NOTE if the default binlog format is changed, this has to be changed
   $used_binlog_format= "stmt";
-  if ( $mysql_version_id >= 50100 )
+  if (!$opt_extern && $mysql_version_id >= 50100 )
   {
     $used_binlog_format= "mixed"; # Default value for binlog format
 
@@ -836,19 +846,20 @@ sub command_line_setup () {
   # --------------------------------------------------------------------------
   # Check im suport
   # --------------------------------------------------------------------------
-  if ( $mysql_version_id < 50000 )
+  if (!$opt_extern)
   {
-    # Instance manager is not supported until 5.0
-    $opt_skip_im= 1;
+    if ( $mysql_version_id < 50000 ) {
+      # Instance manager is not supported until 5.0
+      $opt_skip_im= 1;
 
-  }
+    }
 
-  if ( $glob_win32 )
-  {
-    mtr_report("Disable Instance manager - not supported on Windows");
-    $opt_skip_im= 1;
-  }
+    if ( $glob_win32 ) {
+      mtr_report("Disable Instance manager - not supported on Windows");
+      $opt_skip_im= 1;
+    }
 
+  }
   # --------------------------------------------------------------------------
   # Record flag
   # --------------------------------------------------------------------------
@@ -1212,7 +1223,7 @@ sub command_line_setup () {
     $opt_skip_rpl= 1;
 
     # Setup master->[0] with the settings for the extern server
-    $master->[0]->{'path_sock'}=  $opt_socket if $opt_socket;
+    $master->[0]->{'path_sock'}=  $opt_socket ? $opt_socket : "/tmp/mysql.sock";
     mtr_report("Using extern server at '$master->[0]->{path_sock}'");
   }
   else
@@ -1478,61 +1489,66 @@ sub executable_setup () {
   $exe_mysqlbinlog=    mtr_exe_exists("$path_client_bindir/mysqlbinlog");
   $exe_mysqladmin=     mtr_exe_exists("$path_client_bindir/mysqladmin");
   $exe_mysql=          mtr_exe_exists("$path_client_bindir/mysql");
-  if ( $mysql_version_id >= 50100 )
-  {
-    $exe_mysqlslap=    mtr_exe_exists("$path_client_bindir/mysqlslap");
-  }
-  if ( $mysql_version_id >= 50000 and !$glob_use_embedded_server )
-  {
-    $exe_mysql_upgrade= mtr_exe_exists("$path_client_bindir/mysql_upgrade")
-  }
-  else
-  {
-    $exe_mysql_upgrade= "";
-  }
 
-  if ( ! $glob_win32 )
+  if (!$opt_extern)
   {
-    # Look for mysql_fix_system_table script
-    $exe_mysql_fix_system_tables=
-      mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables",
-			"$path_client_bindir/mysql_fix_privilege_tables");
-  }
-
-  # Look for mysql_fix_privilege_tables.sql script
-  $file_mysql_fix_privilege_tables=
-    mtr_file_exists("$glob_basedir/scripts/mysql_fix_privilege_tables.sql",
-		    "$glob_basedir/share/mysql_fix_privilege_tables.sql");
-
-  if ( ! $opt_skip_ndbcluster and executable_setup_ndb())
-  {
-    mtr_warning("Could not find all required ndb binaries, " .
-		"all ndb tests will fail, use --skip-ndbcluster to " .
-		"skip testing it.");
+    if ( $mysql_version_id >= 50100 )
+    {
+      $exe_mysqlslap=    mtr_exe_exists("$path_client_bindir/mysqlslap");
+    }
+    if ( $mysql_version_id >= 50000 and !$glob_use_embedded_server )
+    {
+      $exe_mysql_upgrade= mtr_exe_exists("$path_client_bindir/mysql_upgrade")
+    }
+    else
+    {
+      $exe_mysql_upgrade= "";
+    }
 
-    foreach my $cluster (@{$clusters})
+    if ( ! $glob_win32 )
     {
-      $cluster->{"executable_setup_failed"}= 1;
+      # Look for mysql_fix_system_table script
+      $exe_mysql_fix_system_tables=
+        mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables",
+  			"$path_client_bindir/mysql_fix_privilege_tables");
     }
-  }
 
-  if ( ! $opt_skip_im and executable_setup_im())
-  {
-    mtr_warning("Could not find all required instance manager binaries, " .
-		"all im tests will fail, use --skip-im to " .
-		"continue without instance manager");
-    $instance_manager->{"executable_setup_failed"}= 1;
-  }
+    # Look for mysql_fix_privilege_tables.sql script
+    $file_mysql_fix_privilege_tables=
+      mtr_file_exists("$glob_basedir/scripts/mysql_fix_privilege_tables.sql",
+  		    "$glob_basedir/share/mysql_fix_privilege_tables.sql");
 
-  # Look for the udf_example library
-  $lib_udf_example=
-    mtr_file_exists(vs_config_dirs('sql', 'udf_example.dll'),
-                    "$glob_basedir/sql/.libs/udf_example.so",);
+    if ( ! $opt_skip_ndbcluster and executable_setup_ndb())
+    {
+      mtr_warning("Could not find all required ndb binaries, " .
+  		"all ndb tests will fail, use --skip-ndbcluster to " .
+  		"skip testing it.");
 
-  # Look for the ha_example library
-  $lib_example_plugin=
-    mtr_file_exists(vs_config_dirs('storage/example', 'ha_example.dll'),
-                    "$glob_basedir/storage/example/.libs/ha_example.so",);
+      foreach my $cluster (@{$clusters})
+      {
+        $cluster->{"executable_setup_failed"}= 1;
+      }
+    }
+
+    if ( ! $opt_skip_im and executable_setup_im())
+    {
+      mtr_warning("Could not find all required instance manager binaries, " .
+  		"all im tests will fail, use --skip-im to " .
+  		"continue without instance manager");
+      $instance_manager->{"executable_setup_failed"}= 1;
+    }
+
+    # Look for the udf_example library
+    $lib_udf_example=
+      mtr_file_exists(vs_config_dirs('sql', 'udf_example.dll'),
+                      "$glob_basedir/sql/.libs/udf_example.so",);
+
+    # Look for the ha_example library
+    $lib_example_plugin=
+      mtr_file_exists(vs_config_dirs('storage/example', 'ha_example.dll'),
+                      "$glob_basedir/storage/example/.libs/ha_example.so",);
+
+  }
 
   # Look for mysqltest executable
   if ( $glob_use_embedded_server )
@@ -1599,7 +1615,7 @@ sub mysql_client_test_arguments()
   mtr_add_arg($args, "--port=$master->[0]->{'port'}");
   mtr_add_arg($args, "--socket=$master->[0]->{'path_sock'}");
 
-  if ( $mysql_version_id >= 50000 )
+  if ( $opt_extern || $mysql_version_id >= 50000 )
   {
     mtr_add_arg($args, "--vardir=$opt_vardir")
   }
@@ -1718,7 +1734,7 @@ sub environment_setup () {
   }
 
   $ENV{'LD_LIBRARY_PATH'}= join(":", @ld_library_paths,
-				$ENV{'LD_LIBRARY_PATHS'} ?
+				$ENV{'LD_LIBRARY_PATH'} ?
 				split(':', $ENV{'LD_LIBRARY_PATH'}) : ());
   mtr_debug("LD_LIBRARY_PATH: $ENV{'LD_LIBRARY_PATH'}");
 
@@ -1899,7 +1915,7 @@ sub environment_setup () {
   my $cmdline_mysqlbinlog=
     "$exe_mysqlbinlog" .
       " --no-defaults --disable-force-if-open --debug-info --local-load=$opt_tmpdir";
-  if ( $mysql_version_id >= 50000 )
+  if ( !$opt_extern && $mysql_version_id >= 50000 )
   {
     $cmdline_mysqlbinlog .=" --character-sets-dir=$path_charsetsdir";
   }
@@ -1930,7 +1946,7 @@ sub environment_setup () {
   # ----------------------------------------------------
   # Setup env so childs can execute mysql_upgrade
   # ----------------------------------------------------
-  if ( $mysql_version_id >= 50000 )
+  if ( !$opt_extern && $mysql_version_id >= 50000 )
   {
     $ENV{'MYSQL_UPGRADE'}= mysql_upgrade_arguments();
   }
@@ -1938,7 +1954,7 @@ sub environment_setup () {
   # ----------------------------------------------------
   # Setup env so childs can execute mysql_fix_system_tables
   # ----------------------------------------------------
-  if ( ! $glob_win32 )
+  if ( !$opt_extern && ! $glob_win32 )
   {
     my $cmdline_mysql_fix_system_tables=
       "$exe_mysql_fix_system_tables --no-defaults --host=localhost " .
@@ -1948,7 +1964,10 @@ sub environment_setup () {
       "--socket=$master->[0]->{'path_sock'}";
     $ENV{'MYSQL_FIX_SYSTEM_TABLES'}=  $cmdline_mysql_fix_system_tables;
   }
-  $ENV{'MYSQL_FIX_PRIVILEGE_TABLES'}=  $file_mysql_fix_privilege_tables;
+  if (!$opt_extern)
+  {
+    $ENV{'MYSQL_FIX_PRIVILEGE_TABLES'}=  $file_mysql_fix_privilege_tables;
+  }
 
   # ----------------------------------------------------
   # Setup env so childs can execute my_print_defaults
@@ -2253,7 +2272,10 @@ sub check_ssl_support ($) {
 
   if ($opt_skip_ssl || $opt_extern)
   {
-    mtr_report("Skipping SSL");
+    if (!$opt_extern)
+    {
+      mtr_report("Skipping SSL");
+    }
     $opt_ssl_supported= 0;
     $opt_ssl= 0;
     return;
@@ -2328,9 +2350,12 @@ sub vs_config_dirs ($$) {
 sub check_ndbcluster_support ($) {
   my $mysqld_variables= shift;
 
-  if ($opt_skip_ndbcluster)
+  if ($opt_skip_ndbcluster || $opt_extern)
   {
-    mtr_report("Skipping ndbcluster");
+    if (!$opt_extern)
+    {
+      mtr_report("Skipping ndbcluster");
+    }
     $opt_skip_ndbcluster_slave= 1;
     return;
   }
@@ -2746,7 +2771,10 @@ sub initialize_servers () {
     }
     else
     {
-      mtr_report("No need to create '$opt_vardir' it already exists");
+      if ($opt_verbose)
+      {
+	mtr_report("No need to create '$opt_vardir' it already exists");
+      }
     }
   }
   else
@@ -3143,17 +3171,17 @@ sub do_before_run_mysqltest($)
   unlink("$result_dir/$tname.log");
   unlink("$result_dir/$tname.warnings");
 
-  if ( $mysql_version_id < 50000 )
-  {
-    # Set environment variable NDB_STATUS_OK to 1
-    # if script decided to run mysqltest cluster _is_ installed ok
-    $ENV{'NDB_STATUS_OK'} = "1";
-  }
-  elsif ( $mysql_version_id < 50100 )
+  if (!$opt_extern)
   {
-    # Set environment variable NDB_STATUS_OK to YES
-    # if script decided to run mysqltest cluster _is_ installed ok
-    $ENV{'NDB_STATUS_OK'} = "YES";
+    if ( $mysql_version_id < 50000 ) {
+      # Set environment variable NDB_STATUS_OK to 1
+      # if script decided to run mysqltest cluster _is_ installed ok
+      $ENV{'NDB_STATUS_OK'} = "1";
+    } elsif ( $mysql_version_id < 50100 ) {
+      # Set environment variable NDB_STATUS_OK to YES
+      # if script decided to run mysqltest cluster _is_ installed ok
+      $ENV{'NDB_STATUS_OK'} = "YES";
+    }
   }
 }
 
@@ -4932,10 +4960,10 @@ sub usage ($) {
 
   if ( $message )
   {
-    print STDERR "$message \n";
+    print STDERR "$message\n";
   }
 
-  print STDERR <<HERE;
+  print <<HERE;
 
 $0 [ OPTIONS ] [ TESTCASE ]
 

--- 1.174/mysql-test/r/innodb.result	2007-02-21 22:20:12 +04:00
+++ 1.175/mysql-test/r/innodb.result	2007-02-28 18:27:03 +04:00
@@ -1984,7 +1984,7 @@ id	select_type	table	type	possible_keys	
 1	SIMPLE	t1	ref	c	c	11	const	#	Using where; Using index
 explain select count(*) from t1 where t='a  ';
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t1	range	t	t	13	NULL	#	Using where
+1	SIMPLE	t1	ref	t	t	13	const	#	Using where
 explain select count(*) from t1 where v like 'a%';
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	SIMPLE	t1	range	v	v	13	NULL	#	Using where; Using index

--- 1.271/storage/innobase/handler/ha_innodb.cc	2007-02-21 22:20:18 +04:00
+++ 1.272/storage/innobase/handler/ha_innodb.cc	2007-02-28 18:27:06 +04:00
@@ -695,7 +695,7 @@ innobase_convert_from_table_id(
 	uint	errors;
 
 	strconvert(current_thd->charset(), from,
-		   &my_charset_filename, to, len, &errors);
+		   &my_charset_filename, to, (uint) len, &errors);
 }
 
 /**********************************************************************
@@ -714,7 +714,7 @@ innobase_convert_from_id(
 	uint	errors;
 
 	strconvert(current_thd->charset(), from,
-		   system_charset_info, to, len, &errors);
+		   system_charset_info, to, (uint) len, &errors);
 }
 
 /**********************************************************************
@@ -839,8 +839,9 @@ innobase_convert_string(
 	CHARSET_INFO*	from_cs,
 	uint*		errors)
 {
-	return(copy_and_convert((char*)to, to_length, to_cs,
-		       (const char*)from, from_length, from_cs, errors));
+  return(copy_and_convert((char*)to, (uint32) to_length, to_cs,
+                          (const char*)from, (uint32) from_length, from_cs,
+                          errors));
 }
 
 /*************************************************************************
@@ -1203,9 +1204,9 @@ innobase_print_identifier(
 		output strings buffers must not be shared.  The function
 		only produces more output when the name contains other
 		characters than [0-9A-Z_a-z]. */
-		char*	temp_name = my_malloc(namelen + 1, MYF(MY_WME));
-		uint	qnamelen = namelen
-				+ (1 + sizeof srv_mysql50_table_name_prefix);
+          char*	temp_name = my_malloc((uint) namelen + 1, MYF(MY_WME));
+          uint	qnamelen = (uint) (namelen
+                                   + (1 + sizeof srv_mysql50_table_name_prefix));
 
 		if (temp_name) {
 			qname = my_malloc(qnamelen, MYF(MY_WME));
@@ -2866,7 +2867,8 @@ ha_innobase::store_key_val_for_row(
 				true_len = (ulint) cs->cset->well_formed_len(cs,
 						(const char *) data,
 						(const char *) data + len,
-						key_len / cs->mbmaxlen,
+                                                (uint) (key_len /
+                                                        cs->mbmaxlen),
 						&error);
 			}
 
@@ -2935,7 +2937,8 @@ ha_innobase::store_key_val_for_row(
 						(const char *) blob_data,
 						(const char *) blob_data
 							+ blob_len,
-						key_len / cs->mbmaxlen,
+                                                (uint) (key_len /
+                                                        cs->mbmaxlen),
 						&error);
 			}
 
@@ -3007,7 +3010,8 @@ ha_innobase::store_key_val_for_row(
 							(const char *)src_start,
 							(const char *)src_start
 								+ key_len,
-							key_len / cs->mbmaxlen,
+                                                        (uint) (key_len /
+                                                                cs->mbmaxlen),
 							&error);
 				}
 			}

--- 1.98/sql/sql_partition.cc	2007-02-21 22:20:15 +04:00
+++ 1.99/sql/sql_partition.cc	2007-02-28 18:27:05 +04:00
@@ -6731,7 +6731,7 @@ int get_part_iter_for_interval_via_mappi
     }
   }
   else
-    DBUG_ASSERT(0);
+    assert(0);
 
   /* 
     Find minimum: Do special handling if the interval has left bound in form

--- 1.69/sql/repl_failsafe.cc	2007-02-21 22:20:14 +04:00
+++ 1.70/sql/repl_failsafe.cc	2007-02-28 18:27:04 +04:00
@@ -73,22 +73,18 @@ static int init_failsafe_rpl_thread(THD*
   thd->net.read_timeout = slave_net_timeout;
   thd->max_client_packet_length=thd->net.max_packet;
   pthread_mutex_lock(&LOCK_thread_count);
-  thd->thread_id = thread_id++;
+  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
   pthread_mutex_unlock(&LOCK_thread_count);
 
   if (init_thr_lock() || thd->store_globals())
   {
+    /* purecov: begin inspected */
     close_connection(thd, ER_OUT_OF_RESOURCES, 1); // is this needed?
     statistic_increment(aborted_connects,&LOCK_status);
-    end_thread(thd,0);
+    one_thread_per_connection_end(thd,0);
     DBUG_RETURN(-1);
+    /* purecov: end */
   }
-
-#if !defined(__WIN__) && !defined(__NETWARE__)
-  sigset_t set;
-  VOID(sigemptyset(&set));			// Get mask in use
-  VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
-#endif
 
   thd->mem_root->free= thd->mem_root->used= 0;
   if (thd->variables.max_join_size == HA_POS_ERROR)

--- 1.158/sql/sql_repl.cc	2007-02-21 22:20:16 +04:00
+++ 1.159/sql/sql_repl.cc	2007-02-28 18:27:05 +04:00
@@ -23,7 +23,9 @@
 
 int max_binlog_dump_events = 0; // unlimited
 my_bool opt_sporadic_binlog_dump_fail = 0;
+#ifndef DBUG_OFF
 static int binlog_dump_count = 0;
+#endif
 
 /*
     fake_rotate_event() builds a fake (=which does not exist physically in any

--- 1.92/sql/ha_ndbcluster_binlog.cc	2007-02-22 01:59:04 +04:00
+++ 1.93/sql/ha_ndbcluster_binlog.cc	2007-02-28 18:27:03 +04:00
@@ -1829,15 +1829,15 @@ ndb_binlog_thread_handle_schema_event(TH
         // fall through
         case SOT_CREATE_TABLE:
           pthread_mutex_lock(&LOCK_open);
-	  if (ndbcluster_check_if_local_table(schema->db, schema->name))
-	  {
-	    DBUG_PRINT("info", ("NDB binlog: Skipping locally defined table '%s.%s'",
-				schema->db, schema->name));
+          if (ndbcluster_check_if_local_table(schema->db, schema->name))
+          {
+            DBUG_PRINT("info", ("NDB binlog: Skipping locally defined table '%s.%s'",
+                                schema->db, schema->name));
             sql_print_error("NDB binlog: Skipping locally defined table '%s.%s' from "
                             "binlog schema event '%s' from node %d. ",
                             schema->db, schema->name, schema->query,
                             schema->node_id);
-	  }
+          }
           else if (ndb_create_table_from_engine(thd, schema->db, schema->name))
           {
             sql_print_error("NDB binlog: Could not discover table '%s.%s' from "
@@ -1854,27 +1854,27 @@ ndb_binlog_thread_handle_schema_event(TH
           log_query= 1;
           break;
         case SOT_DROP_DB:
-	  /* Drop the database locally if it only contains ndb tables */
-	  if (! ndbcluster_check_if_local_tables_in_db(thd, schema->db))
-	  {
-	    run_query(thd, schema->query,
-		      schema->query + schema->query_length,
-		      TRUE,    /* print error */
-		      TRUE);   /* don't binlog the query */
-	    /* binlog dropping database after any table operations */
-	    post_epoch_log_list->push_back(schema, mem_root);
-	    /* acknowledge this query _after_ epoch completion */
-	    post_epoch_unlock= 1;
-	  }
-	  else
-	  {
-	    /* Database contained local tables, leave it */
-	    sql_print_error("NDB binlog: Skipping drop database '%s' since it contained local tables "
+          /* Drop the database locally if it only contains ndb tables */
+          if (! ndbcluster_check_if_local_tables_in_db(thd, schema->db))
+          {
+            run_query(thd, schema->query,
+                      schema->query + schema->query_length,
+                      TRUE,    /* print error */
+                      TRUE);   /* don't binlog the query */
+            /* binlog dropping database after any table operations */
+            post_epoch_log_list->push_back(schema, mem_root);
+            /* acknowledge this query _after_ epoch completion */
+            post_epoch_unlock= 1;
+          }
+          else
+          {
+            /* Database contained local tables, leave it */
+            sql_print_error("NDB binlog: Skipping drop database '%s' since it contained local tables "
                             "binlog schema event '%s' from node %d. ",
                             schema->db, schema->query,
                             schema->node_id);
-	    log_query= 1;
-	  }
+            log_query= 1;
+          }
           break;
         case SOT_CREATE_DB:
           /* fall through */
@@ -2121,18 +2121,18 @@ ndb_binlog_thread_handle_schema_event_po
             share= 0;
           }
           pthread_mutex_lock(&LOCK_open);
-	  if (ndbcluster_check_if_local_table(schema->db, schema->name))
-	  {
-	    DBUG_PRINT("info", ("NDB binlog: Skipping locally defined table '%s.%s'",
-				schema->db, schema->name));
+          if (ndbcluster_check_if_local_table(schema->db, schema->name))
+          {
+            DBUG_PRINT("info", ("NDB binlog: Skipping locally defined table '%s.%s'",
+                                schema->db, schema->name));
             sql_print_error("NDB binlog: Skipping locally defined table '%s.%s' from "
                             "binlog schema event '%s' from node %d. ",
                             schema->db, schema->name, schema->query,
                             schema->node_id);
-	  }
+          }
           else if (ndb_create_table_from_engine(thd, schema->db, schema->name))
-	  {
-	    sql_print_error("NDB binlog: Could not discover table '%s.%s' from "
+          {
+            sql_print_error("NDB binlog: Could not discover table '%s.%s' from "
                             "binlog schema event '%s' from node %d. my_errno: %d",
                             schema->db, schema->name, schema->query,
                             schema->node_id, my_errno);
@@ -2260,7 +2260,7 @@ int ndb_add_ndb_binlog_index(THD *thd, v
       {
         TABLE_LIST *p_binlog_tables= &binlog_tables;
         close_tables_for_reopen(thd, &p_binlog_tables);
-	ndb_binlog_index= 0;
+        ndb_binlog_index= 0;
         continue;
       }
       sql_print_error("NDB Binlog: Unable to lock table ndb_binlog_index");
@@ -3225,15 +3225,17 @@ ndb_binlog_thread_handle_data_event(Ndb 
       if (share->flags & NSF_BLOB_FLAG)
       {
         my_ptrdiff_t ptrdiff= 0;
-        int ret= get_ndb_blobs_value(table, share->ndb_value[0],
-                                     blobs_buffer[0], blobs_buffer_size[0],
-                                     ptrdiff);
+        IF_DBUG(int ret =) get_ndb_blobs_value(table, share->ndb_value[0],
+                                               blobs_buffer[0],
+                                               blobs_buffer_size[0],
+                                               ptrdiff);
         DBUG_ASSERT(ret == 0);
       }
       ndb_unpack_record(table, share->ndb_value[0], &b, table->record[0]);
-      int ret= trans.write_row(::server_id,
-                               injector::transaction::table(table, TRUE),
-                               &b, n_fields, table->record[0]);
+      IF_DBUG(int ret=) trans.write_row(::server_id,
+                                        injector::transaction::table(table,
+                                                                     TRUE),
+                                        &b, n_fields, table->record[0]);
       DBUG_ASSERT(ret == 0);
     }
     break;
@@ -3251,27 +3253,29 @@ ndb_binlog_thread_handle_data_event(Ndb 
         n= 0; /*
                 use the primary key only as it save time and space and
                 it is the only thing needed to log the delete
-	      */
+              */
       else
         n= 1; /*
                 we use the before values since we don't have a primary key
                 since the mysql server does not handle the hidden primary
                 key
-	      */
+              */
 
       if (share->flags & NSF_BLOB_FLAG)
       {
         my_ptrdiff_t ptrdiff= table->record[n] - table->record[0];
-        int ret= get_ndb_blobs_value(table, share->ndb_value[n],
-                                     blobs_buffer[n], blobs_buffer_size[n],
-                                     ptrdiff);
+        IF_DBUG(int ret =) get_ndb_blobs_value(table, share->ndb_value[n],
+                                               blobs_buffer[n],
+                                               blobs_buffer_size[n],
+                                               ptrdiff);
         DBUG_ASSERT(ret == 0);
       }
       ndb_unpack_record(table, share->ndb_value[n], &b, table->record[n]);
       DBUG_EXECUTE("info", print_records(table, table->record[n]););
-      int ret= trans.delete_row(::server_id,
-                                injector::transaction::table(table, TRUE),
-                                &b, n_fields, table->record[n]);
+      IF_DBUG(int ret =) trans.delete_row(::server_id,
+                                          injector::transaction::table(table,
+                                                                       TRUE),
+                                          &b, n_fields, table->record[n]);
       DBUG_ASSERT(ret == 0);
     }
     break;
@@ -3283,9 +3287,10 @@ ndb_binlog_thread_handle_data_event(Ndb 
       if (share->flags & NSF_BLOB_FLAG)
       {
         my_ptrdiff_t ptrdiff= 0;
-        int ret= get_ndb_blobs_value(table, share->ndb_value[0],
-                                     blobs_buffer[0], blobs_buffer_size[0],
-                                     ptrdiff);
+        IF_DBUG(int ret =) get_ndb_blobs_value(table, share->ndb_value[0],
+                                               blobs_buffer[0],
+                                               blobs_buffer_size[0],
+                                               ptrdiff);
         DBUG_ASSERT(ret == 0);
       }
       ndb_unpack_record(table, share->ndb_value[0],
@@ -3296,7 +3301,7 @@ ndb_binlog_thread_handle_data_event(Ndb 
         /*
           since table has a primary key, we can do a write
           using only after values
-	*/
+        */
         trans.write_row(::server_id, injector::transaction::table(table, TRUE),
                         &b, n_fields, table->record[0]);// after values
       }
@@ -3305,22 +3310,24 @@ ndb_binlog_thread_handle_data_event(Ndb 
         /*
           mysql server cannot handle the ndb hidden key and
           therefore needs the before image as well
-	*/
+        */
         if (share->flags & NSF_BLOB_FLAG)
         {
           my_ptrdiff_t ptrdiff= table->record[1] - table->record[0];
-          int ret= get_ndb_blobs_value(table, share->ndb_value[1],
-                                       blobs_buffer[1], blobs_buffer_size[1],
-                                       ptrdiff);
+          IF_DBUG(int ret =) get_ndb_blobs_value(table, share->ndb_value[1],
+                                                 blobs_buffer[1],
+                                                 blobs_buffer_size[1],
+                                                 ptrdiff);
           DBUG_ASSERT(ret == 0);
         }
         ndb_unpack_record(table, share->ndb_value[1], &b, table->record[1]);
         DBUG_EXECUTE("info", print_records(table, table->record[1]););
-        int ret= trans.update_row(::server_id,
-                                  injector::transaction::table(table, TRUE),
-                                  &b, n_fields,
-                                  table->record[1], // before values
-                                  table->record[0]);// after values
+        IF_DBUG(int ret =) trans.update_row(::server_id,
+                                            injector::transaction::table(table,
+                                                                         TRUE),
+                                            &b, n_fields,
+                                            table->record[1], // before values
+                                            table->record[0]);// after values
         DBUG_ASSERT(ret == 0);
       }
     }
@@ -3850,7 +3857,9 @@ restart:
               continue;
             }
             TABLE *table= share->table;
+#ifndef DBUG_OFF
             const LEX_STRING &name= table->s->table_name;
+#endif
             if ((event_types & (NdbDictionary::Event::TE_INSERT |
                                 NdbDictionary::Event::TE_UPDATE |
                                 NdbDictionary::Event::TE_DELETE)) == 0)
@@ -3867,7 +3876,7 @@ restart:
             }
             DBUG_PRINT("info", ("use_table: %.*s", name.length, name.str));
             injector::transaction::table tbl(table, TRUE);
-            int ret= trans.use_table(::server_id, tbl);
+            IF_DBUG(int ret=) trans.use_table(::server_id, tbl);
             DBUG_ASSERT(ret == 0);
           }
         }
@@ -3877,10 +3886,12 @@ restart:
           {
             TABLE *table= ndb_apply_status_share->table;
 
-            const LEX_STRING& name=table->s->table_name;
+#ifndef DBUG_OFF
+            const LEX_STRING& name= table->s->table_name;
             DBUG_PRINT("info", ("use_table: %.*s", name.length, name.str));
+#endif
             injector::transaction::table tbl(table, TRUE);
-            int ret= trans.use_table(::server_id, tbl);
+            IF_DBUG(int ret=) trans.use_table(::server_id, tbl);
             DBUG_ASSERT(ret == 0);
 
             // Set all fields non-null.
@@ -3945,7 +3956,7 @@ restart:
           else
           {
             // set injector_ndb database/schema from table internal name
-            int ret=
+            IF_DBUG(int ret=)
               i_ndb->setDatabaseAndSchemaName(pOp->getEvent()->getTable());
             DBUG_ASSERT(ret == 0);
             ndb_binlog_thread_handle_non_data_event(thd, i_ndb, pOp, row);
@@ -3979,7 +3990,7 @@ restart:
         /*
           note! pOp is not referring to an event in the next epoch
           or is == 0
-	*/
+        */
 #ifdef RUN_NDB_BINLOG_TIMER
         write_timer.stop();
 #endif
Thread
bk commit into 5.2 tree (gluh:1.2454)gluh28 Feb