List:Commits« Previous MessageNext Message »
From:Jim Winstead Date:December 12 2005 7:57pm
Subject:bk commit into 5.1 tree (jimw:1.1958)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of jimw. When jimw does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.1958 05/12/12 11:57:07 jimw@stripped +22 -0
  Merge mysql.com:/home/jimw/my/mysql-5.0-clean
  into  mysql.com:/home/jimw/my/mysql-5.1-clean

  sql/sql_base.cc
    1.286 05/12/12 11:57:02 jimw@stripped +1 -1
    Resolve conflict

  sql/sql_yacc.yy
    1.430 05/12/12 11:55:14 jimw@stripped +0 -0
    Auto merged

  sql/sql_update.cc
    1.179 05/12/12 11:55:14 jimw@stripped +0 -0
    Auto merged

  sql/sql_select.cc
    1.375 05/12/12 11:55:13 jimw@stripped +0 -0
    Auto merged

  sql/sql_prepare.cc
    1.157 05/12/12 11:55:13 jimw@stripped +0 -0
    Auto merged

  sql/sql_parse.cc
    1.497 05/12/12 11:55:13 jimw@stripped +0 -0
    Auto merged

  sql/sql_lex.h
    1.210 05/12/12 11:55:13 jimw@stripped +0 -0
    Auto merged

  sql/sql_lex.cc
    1.169 05/12/12 11:55:13 jimw@stripped +0 -0
    Auto merged

  sql/sql_insert.cc
    1.178 05/12/12 11:55:13 jimw@stripped +0 -0
    Auto merged

  sql/sql_delete.cc
    1.160 05/12/12 11:55:13 jimw@stripped +0 -0
    Auto merged

  sql/sql_db.cc
    1.122 05/12/12 11:55:13 jimw@stripped +0 -0
    Auto merged

  sql/sql_class.h
    1.277 05/12/12 11:55:13 jimw@stripped +0 -0
    Auto merged

  sql/sql_class.cc
    1.224 05/12/12 11:55:12 jimw@stripped +0 -0
    Auto merged

  sql/mysql_priv.h
    1.354 05/12/12 11:55:12 jimw@stripped +0 -0
    Auto merged

  sql/item_sum.cc
    1.171 05/12/12 11:55:12 jimw@stripped +0 -0
    Auto merged

  sql/item_subselect.cc
    1.121 05/12/12 11:55:12 jimw@stripped +0 -0
    Auto merged

  sql/item_strfunc.cc
    1.262 05/12/12 11:55:12 jimw@stripped +0 -0
    Auto merged

  sql/item_func.cc
    1.271 05/12/12 11:55:12 jimw@stripped +0 -0
    Auto merged

  sql/item_cmpfunc.cc
    1.188 05/12/12 11:55:12 jimw@stripped +0 -0
    Auto merged

  sql/item.h
    1.184 05/12/12 11:55:12 jimw@stripped +0 -0
    Auto merged

  sql/item.cc
    1.161 05/12/12 11:55:12 jimw@stripped +0 -0
    Auto merged

  mysql-test/r/sp.result
    1.176 05/12/12 11:55:12 jimw@stripped +0 -0
    Auto merged

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	jimw
# Host:	rama.(none)
# Root:	/home/jimw/my/mysql-5.1-clean/RESYNC

--- 1.160/sql/item.cc	2005-12-09 03:39:39 -08:00
+++ 1.161/sql/item.cc	2005-12-12 11:55:12 -08:00
@@ -1084,6 +1084,7 @@
     ref_pointer_array	Pointer to array of reference fields
     fields		All fields in select
     ref			Pointer to item
+    skip_registered     <=> function be must skipped for registered SUM items
 
   NOTES
    This is from split_sum_func2() for items that should be split
@@ -1096,8 +1097,13 @@
 
 
 void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
-                           List<Item> &fields, Item **ref)
+                           List<Item> &fields, Item **ref, 
+                           bool skip_registered)
 {
+  /* An item of type Item_sum  is registered <=> ref_by != 0 */ 
+  if (type() == SUM_FUNC_ITEM && skip_registered && 
+      ((Item_sum *) this)->ref_by)
+    return;                                                 
   if (type() != SUM_FUNC_ITEM && with_sum_func)
   {
     /* Will split complicated items and ignore simple ones */
@@ -3232,14 +3238,8 @@
         {
           for each outer query Q_k beginning from the inner-most one
           {
-            if - Q_k is not a group query AND
-               - Q_k is not inside an aggregate function
-               OR
-               - Q_(k-1) is not in a HAVING or SELECT clause of Q_k
-            {
-              search for a column or derived column named col_ref_i
-              [in table T_j] in the FROM clause of Q_k;
-            }
+            search for a column or derived column named col_ref_i
+            [in table T_j] in the FROM clause of Q_k;
 
             if such a column is not found
               Search for a column or derived column named col_ref_i
@@ -3318,18 +3318,11 @@
 
         place= prev_subselect_item->parsing_place;
         /*
-          Check table fields only if the subquery is used somewhere out of
-          HAVING, or the outer SELECT does not use grouping (i.e. tables are
-          accessible).
-
           In case of a view, find_field_in_tables() writes the pointer to
           the found view field into '*reference', in other words, it
           substitutes this Item_field with the found expression.
         */
-        if ((place != IN_HAVING ||
-             (!select->with_sum_func &&
-              select->group_list.elements == 0)) &&
-            (from_field= find_field_in_tables(thd, this,
+        if ((from_field= find_field_in_tables(thd, this,
                                               outer_context->
                                                 first_name_resolution_table,
                                               outer_context->
@@ -3345,6 +3338,21 @@
             {
               prev_subselect_item->used_tables_cache|= from_field->table->map;
               prev_subselect_item->const_item_cache= 0;
+              if (thd->lex->in_sum_func &&
+                  thd->lex->in_sum_func->nest_level == 
+                  thd->lex->current_select->nest_level)
+              {
+                Item::Type type= (*reference)->type();
+                set_if_bigger(thd->lex->in_sum_func->max_arg_level,
+                              select->nest_level);
+                set_field(from_field);
+                fixed= 1;
+                mark_as_dependent(thd, last_checked_context->select_lex,
+                                  context->select_lex, this,
+                                  ((type == REF_ITEM || type == FIELD_ITEM) ?
+                                   (Item_ident*) (*reference) : 0));
+                return FALSE;
+              }
             }
             else
             {
@@ -3496,6 +3504,11 @@
       return FALSE;
 
     set_field(from_field);
+    if (thd->lex->in_sum_func &&
+        thd->lex->in_sum_func->nest_level == 
+        thd->lex->current_select->nest_level)
+      set_if_bigger(thd->lex->in_sum_func->max_arg_level,
+                    thd->lex->current_select->nest_level);
   }
   else if (thd->set_query_id)
   {
@@ -4688,9 +4701,8 @@
     aggregate function.
   */
   if (((*ref)->with_sum_func && name &&
-       (depended_from ||
-	!(current_sel->linkage != GLOBAL_OPTIONS_TYPE &&
-          current_sel->having_fix_field))) ||
+       !(current_sel->linkage != GLOBAL_OPTIONS_TYPE &&
+         current_sel->having_fix_field)) ||
       !(*ref)->fixed)
   {
     my_error(ER_ILLEGAL_REFERENCE, MYF(0),
@@ -5184,10 +5196,17 @@
     Item_ref *ref= (Item_ref *)arg;
     if (ref->ref[0]->type() != FIELD_ITEM)
     {
+      my_error(ER_BAD_FIELD_ERROR, MYF(0), "", "VALUES() function");
       return TRUE;
     }
     arg= ref->ref[0];
   }
+  /*
+    According to our SQL grammar, VALUES() function can reference
+    only to a column.
+  */
+  DBUG_ASSERT(arg->type() == FIELD_ITEM);
+
   Item_field *field_arg= (Item_field *)arg;
 
   if (field_arg->field->table->insert_values)

--- 1.183/sql/item.h	2005-12-10 23:30:51 -08:00
+++ 1.184/sql/item.h	2005-12-12 11:55:12 -08:00
@@ -729,7 +729,7 @@
   // used in row subselects to get value of elements
   virtual void bring_value() {}
 
-  Field *tmp_table_field_from_field_type(TABLE *table);
+  Field *tmp_table_field_from_field_type(TABLE *table, bool fixed_length);
   virtual Item_field *filed_for_view_update() { return 0; }
 
   virtual Item *neg_transformer(THD *thd) { return NULL; }

--- 1.187/sql/item_cmpfunc.cc	2005-12-02 20:42:27 -08:00
+++ 1.188/sql/item_cmpfunc.cc	2005-12-12 11:55:12 -08:00
@@ -1232,7 +1232,7 @@
 
 Field *Item_func_ifnull::tmp_table_field(TABLE *table)
 {
-  return tmp_table_field_from_field_type(table);
+  return tmp_table_field_from_field_type(table, 0);
 }
 
 double

--- 1.270/sql/item_func.cc	2005-12-10 23:30:51 -08:00
+++ 1.271/sql/item_func.cc	2005-12-12 11:55:12 -08:00
@@ -362,41 +362,43 @@
 }
 
 
-Field *Item_func::tmp_table_field(TABLE *t_arg)
+Field *Item_func::tmp_table_field(TABLE *table)
 {
-  Field *res;
-  LINT_INIT(res);
+  Field *field;
+  LINT_INIT(field);
 
   switch (result_type()) {
   case INT_RESULT:
     if (max_length > 11)
-      res= new Field_longlong(max_length, maybe_null, name, t_arg,
-			      unsigned_flag);
+      field= new Field_longlong(max_length, maybe_null, name, unsigned_flag);
     else
-      res= new Field_long(max_length, maybe_null, name, t_arg,
-			  unsigned_flag);
+      field= new Field_long(max_length, maybe_null, name, unsigned_flag);
     break;
   case REAL_RESULT:
-    res= new Field_double(max_length, maybe_null, name, t_arg, decimals);
+    field= new Field_double(max_length, maybe_null, name, decimals);
     break;
   case STRING_RESULT:
-    res= make_string_field(t_arg);
+    return make_string_field(table);
     break;
   case DECIMAL_RESULT:
-    res= new Field_new_decimal(my_decimal_precision_to_length(decimal_precision(),
-                                                              decimals,
-                                                              unsigned_flag),
-                               maybe_null, name, t_arg, decimals, unsigned_flag);
+    field= new Field_new_decimal(my_decimal_precision_to_length(decimal_precision(),
+                                                                decimals,
+                                                                unsigned_flag),
+                                 maybe_null, name, decimals, unsigned_flag);
     break;
   case ROW_RESULT:
   default:
     // This case should never be chosen
     DBUG_ASSERT(0);
+    field= 0;
     break;
   }
-  return res;
+  if (field)
+    field->init(table);
+  return field;
 }
 
+
 my_decimal *Item_func::val_decimal(my_decimal *decimal_value)
 {
   DBUG_ASSERT(fixed);
@@ -4637,7 +4639,8 @@
 {
   maybe_null= 1;
   m_name->init_qname(current_thd);
-  dummy_table= (TABLE*) sql_calloc(sizeof(TABLE));
+  dummy_table= (TABLE*) sql_calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE));
+  dummy_table->s= (TABLE_SHARE*) (dummy_table+1);
 }
 
 
@@ -4648,9 +4651,11 @@
 {
   maybe_null= 1;
   m_name->init_qname(current_thd);
-  dummy_table= (TABLE*) sql_calloc(sizeof(TABLE));
+  dummy_table= (TABLE*) sql_calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE));
+  dummy_table->s= (TABLE_SHARE*) (dummy_table+1);
 }
 
+
 void
 Item_func_sp::cleanup()
 {
@@ -4705,16 +4710,15 @@
       DBUG_RETURN(0);
     }
   }
-  if (!dummy_table->s)
+  if (!dummy_table->alias)
   {
     char *empty_name= (char *) "";
-    TABLE_SHARE *share;
-    dummy_table->s= share= &dummy_table->share_not_to_be_used;      
-    dummy_table->alias = empty_name;
-    dummy_table->maybe_null = maybe_null;
+    dummy_table->alias= empty_name;
+    dummy_table->maybe_null= maybe_null;
     dummy_table->in_use= current_thd;
-    share->table_cache_key = empty_name;
-    share->table_name = empty_name;
+    dummy_table->s->table_cache_key.str = empty_name;
+    dummy_table->s->table_name.str= empty_name;
+    dummy_table->s->db.str= empty_name;
   }
   field= m_sp->create_result_field(max_length, name, dummy_table);
   DBUG_RETURN(field);

--- 1.170/sql/item_sum.cc	2005-12-02 20:42:27 -08:00
+++ 1.171/sql/item_sum.cc	2005-12-12 11:55:12 -08:00
@@ -371,26 +371,33 @@
 Field *Item_sum::create_tmp_field(bool group, TABLE *table,
                                   uint convert_blob_length)
 {
+  Field *field;
   switch (result_type()) {
   case REAL_RESULT:
-    return new Field_double(max_length,maybe_null,name,table,decimals);
+    field= new Field_double(max_length, maybe_null, name, decimals);
+    break;
   case INT_RESULT:
-    return new Field_longlong(max_length,maybe_null,name,table,unsigned_flag);
+    field= new Field_longlong(max_length, maybe_null, name, unsigned_flag);
+    break;
   case STRING_RESULT:
-    if (max_length > 255 && convert_blob_length)
-      return new Field_varstring(convert_blob_length, maybe_null,
-                                 name, table,
-                                 collation.collation);
-    return make_string_field(table);
+    if (max_length <= 255 || !convert_blob_length)
+      return make_string_field(table);
+    field= new Field_varstring(convert_blob_length, maybe_null,
+                               name, table->s, collation.collation);
+    break;
   case DECIMAL_RESULT:
-    return new Field_new_decimal(max_length, maybe_null, name, table,
+    field= new Field_new_decimal(max_length, maybe_null, name,
                                  decimals, unsigned_flag);
+    break;
   case ROW_RESULT:
   default:
     // This case should never be choosen
     DBUG_ASSERT(0);
     return 0;
   }
+  if (field)
+    field->init(table);
+  return field;
 }
 
 
@@ -538,9 +545,10 @@
 Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
 					 uint convert_blob_length)
 {
+  Field *field;
   if (args[0]->type() == Item::FIELD_ITEM)
   {
-    Field *field= ((Item_field*) args[0])->field;
+    field= ((Item_field*) args[0])->field;
     
     if ((field= create_tmp_field_from_field(current_thd, field, name, table,
 					    NULL, convert_blob_length)))
@@ -554,16 +562,21 @@
   */
   switch (args[0]->field_type()) {
   case MYSQL_TYPE_DATE:
-    return new Field_date(maybe_null, name, table, collation.collation);
+    field= new Field_date(maybe_null, name, collation.collation);
+    break;
   case MYSQL_TYPE_TIME:
-    return new Field_time(maybe_null, name, table, collation.collation);
+    field= new Field_time(maybe_null, name, collation.collation);
+    break;
   case MYSQL_TYPE_TIMESTAMP:
   case MYSQL_TYPE_DATETIME:
-    return new Field_datetime(maybe_null, name, table, collation.collation);
-  default:
+    field= new Field_datetime(maybe_null, name, collation.collation);
     break;
+  default:
+    return Item_sum::create_tmp_field(group, table, convert_blob_length);
   }
-  return Item_sum::create_tmp_field(group, table, convert_blob_length);
+  if (field)
+    field->init(table);
+  return field;
 }
 
 
@@ -1065,6 +1078,7 @@
 Field *Item_sum_avg::create_tmp_field(bool group, TABLE *table,
                                       uint convert_blob_len)
 {
+  Field *field;
   if (group)
   {
     /*
@@ -1072,14 +1086,18 @@
       The easyest way is to do this is to store both value in a string
       and unpack on access.
     */
-    return new Field_string(((hybrid_type == DECIMAL_RESULT) ?
+    field= new Field_string(((hybrid_type == DECIMAL_RESULT) ?
                              dec_bin_size : sizeof(double)) + sizeof(longlong),
-                            0, name, table, &my_charset_bin);
+                            0, name, &my_charset_bin);
   }
-  if (hybrid_type == DECIMAL_RESULT)
-    return new Field_new_decimal(max_length, maybe_null, name, table,
+  else if (hybrid_type == DECIMAL_RESULT)
+    field= new Field_new_decimal(max_length, maybe_null, name,
                                  decimals, unsigned_flag);
-  return new Field_double(max_length, maybe_null, name, table, decimals);
+  else
+    field= new Field_double(max_length, maybe_null, name, decimals);
+  if (field)
+    field->init(table);
+  return field;
 }
 
 
@@ -1244,6 +1262,7 @@
 Field *Item_sum_variance::create_tmp_field(bool group, TABLE *table,
                                            uint convert_blob_len)
 {
+  Field *field;
   if (group)
   {
     /*
@@ -1251,15 +1270,19 @@
       The easyest way is to do this is to store both value in a string
       and unpack on access.
     */
-    return new Field_string(((hybrid_type == DECIMAL_RESULT) ?
+    field= new Field_string(((hybrid_type == DECIMAL_RESULT) ?
                              dec_bin_size0 + dec_bin_size1 :
                              sizeof(double)*2) + sizeof(longlong),
-                            0, name, table, &my_charset_bin);
+                            0, name, &my_charset_bin);
   }
-  if (hybrid_type == DECIMAL_RESULT)
-    return new Field_new_decimal(max_length, maybe_null, name, table,
+  else if (hybrid_type == DECIMAL_RESULT)
+    field= new Field_new_decimal(max_length, maybe_null, name,
                                  decimals, unsigned_flag);
-  return new Field_double(max_length, maybe_null,name,table,decimals);
+  else
+    field= new Field_double(max_length, maybe_null, name, decimals);
+  if (field)
+    field->init(table);
+  return field;
 }
 
 

--- 1.353/sql/mysql_priv.h	2005-12-09 03:39:39 -08:00
+++ 1.354/sql/mysql_priv.h	2005-12-12 11:55:12 -08:00
@@ -48,6 +48,7 @@
 typedef Bitmap<((MAX_INDEXES+7)/8*8)> key_map; /* Used for finding keys */
 #endif
 typedef ulong key_part_map;           /* Used for finding key parts */
+typedef ulong nesting_map;  /* Used for flags of nesting constructs */
 /*
   Used to identify NESTED_JOIN structures within a join (applicable only to
   structures that have not been simplified away and embed more the one

--- 1.285/sql/sql_base.cc	2005-12-12 03:59:05 -08:00
+++ 1.286/sql/sql_base.cc	2005-12-12 11:57:02 -08:00
@@ -4942,11 +4942,13 @@
 {
   reg2 Item *item;
   ulong save_set_query_id= thd->set_query_id;
+  nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
   List_iterator<Item> it(fields);
   DBUG_ENTER("setup_fields");
 
   thd->set_query_id=set_query_id;
-  thd->allow_sum_func= allow_sum_func;
+  if (allow_sum_func)
+    thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
   thd->where= THD::DEFAULT_WHERE;
 
   /*
@@ -4969,6 +4971,7 @@
     if (!item->fixed && item->fix_fields(thd, it.ref()) ||
 	(item= *(it.ref()))->check_cols(1))
     {
+      thd->lex->allow_sum_func= save_allow_sum_func;
       thd->set_query_id= save_set_query_id;
       DBUG_RETURN(TRUE); /* purecov: inspected */
     }
@@ -4979,6 +4982,7 @@
       item->split_sum_func(thd, ref_pointer_array, *sum_func_list);
     thd->used_tables|= item->used_tables();
   }
+  thd->lex->allow_sum_func= save_allow_sum_func;
   thd->set_query_id= save_set_query_id;
   DBUG_RETURN(test(thd->net.report_error));
 }

--- 1.223/sql/sql_class.cc	2005-12-10 23:30:52 -08:00
+++ 1.224/sql/sql_class.cc	2005-12-12 11:55:12 -08:00
@@ -288,7 +288,7 @@
 					       variables.date_format);
   variables.datetime_format= date_time_format_copy((THD*) 0,
 						   variables.datetime_format);
-#ifdef HAVE_NDBCLUSTER_DB
+#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
   variables.ndb_use_transactions= 1;
 #endif
   pthread_mutex_unlock(&LOCK_global_system_variables);
@@ -665,7 +665,8 @@
 
   DBUG_ASSERT((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
 	      table->file->has_transactions());
-  add_changed_table(table->s->table_cache_key, table->s->key_length);
+  add_changed_table(table->s->table_cache_key.str,
+                    table->s->table_cache_key.length);
   DBUG_VOID_RETURN;
 }
 
@@ -909,7 +910,7 @@
     return 0;
   }
 
-#ifdef HAVE_INNOBASE_DB
+#ifdef WITH_INNOBASE_STORAGE_ENGINE
   /*
     We may be passing the control from mysqld to the client: release the
     InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
@@ -945,7 +946,7 @@
 
 bool select_send::send_eof()
 {
-#ifdef HAVE_INNOBASE_DB
+#ifdef WITH_INNOBASE_STORAGE_ENGINE
   /* We may be passing the control from mysqld to the client: release the
      InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
      by thd */
@@ -1060,7 +1061,8 @@
 
   if (!dirname_length(exchange->file_name))
   {
-    strxnmov(path, FN_REFLEN, mysql_real_data_home, thd->db ? thd->db : "", NullS);
+    strxnmov(path, FN_REFLEN-1, mysql_real_data_home, thd->db ? thd->db : "",
+             NullS);
     (void) fn_format(path, exchange->file_name, path, "", option);
   }
   else

--- 1.276/sql/sql_class.h	2005-12-12 03:30:12 -08:00
+++ 1.277/sql/sql_class.h	2005-12-12 11:55:13 -08:00
@@ -791,19 +791,6 @@
        and update_row
   */
   ulong set_query_id;
-  /*
-    This variable is used in post-parse stage to declare that sum-functions,
-    or functions which have sense only if GROUP BY is present, are allowed.
-    For example in queries
-    SELECT MIN(i) FROM foo
-    SELECT GROUP_CONCAT(a, b, MIN(i)) FROM ... GROUP BY ...
-    MIN(i) have no sense.
-    Though it's grammar-related issue, it's hard to catch it out during the
-    parse stage because GROUP BY clause goes in the end of query. This
-    variable is mainly used in setup_fields/fix_fields.
-    See item_sum.cc for details.
-  */
-  bool allow_sum_func;
 
   LEX_STRING name; /* name for named prepared statements */
   LEX *lex;                                     // parse tree descriptor

--- 1.121/sql/sql_db.cc	2005-11-23 12:44:56 -08:00
+++ 1.122/sql/sql_db.cc	2005-12-12 11:55:13 -08:00
@@ -1162,10 +1162,12 @@
     DBUG_RETURN(1);
   }
 end:
-  x_free(thd->db);
+  if (!(thd->slave_thread))
+    x_free(thd->db);
   if (dbname && dbname[0] == 0)
   {
-    x_free(dbname);
+    if (!(thd->slave_thread))
+      x_free(dbname);
     thd->db= NULL;
     thd->db_length= 0;
   }

--- 1.159/sql/sql_delete.cc	2005-11-23 12:44:56 -08:00
+++ 1.160/sql/sql_delete.cc	2005-12-12 11:55:13 -08:00
@@ -301,6 +301,7 @@
     if (!transactional_table)
       thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
   }
+  free_underlaid_joins(thd, select_lex);
   if (transactional_table)
   {
     if (ha_autocommit_or_rollback(thd,error >= 0))
@@ -312,7 +313,6 @@
     mysql_unlock_tables(thd, thd->lock);
     thd->lock=0;
   }
-  free_underlaid_joins(thd, select_lex);
   if (error < 0)
   {
     thd->row_count_func= deleted;
@@ -341,7 +341,7 @@
   SELECT_LEX *select_lex= &thd->lex->select_lex;
   DBUG_ENTER("mysql_prepare_delete");
 
-  thd->allow_sum_func= 0;
+  thd->lex->allow_sum_func= 0;
   if (setup_tables(thd, &thd->lex->select_lex.context,
                    &thd->lex->select_lex.top_join_list,
                    table_list, conds, &select_lex->leaf_tables,

--- 1.177/sql/sql_insert.cc	2005-12-06 22:28:11 -08:00
+++ 1.178/sql/sql_insert.cc	2005-12-12 11:55:13 -08:00
@@ -270,7 +270,7 @@
   */
   bool log_on= (thd->options & OPTION_BIN_LOG) ||
     (!(thd->security_ctx->master_access & SUPER_ACL));
-  bool transactional_table;
+  bool transactional_table, joins_freed= FALSE;
   uint value_count;
   ulong counter = 1;
   ulonglong id;
@@ -526,6 +526,9 @@
     thd->row_count++;
   }
 
+  free_underlaid_joins(thd, &thd->lex->select_lex);
+  joins_freed= TRUE;
+
   /*
     Now all rows are inserted.  Time to update logs and sends response to
     user
@@ -624,7 +627,6 @@
     thd->row_count_func= info.copied+info.deleted+info.updated;
     ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
   }
-  free_underlaid_joins(thd, &thd->lex->select_lex);
   thd->abort_on_warning= 0;
   DBUG_RETURN(FALSE);
 
@@ -633,7 +635,8 @@
   if (lock_type == TL_WRITE_DELAYED)
     end_delayed_insert(thd);
 #endif
-  free_underlaid_joins(thd, &thd->lex->select_lex);
+  if (!joins_freed)
+    free_underlaid_joins(thd, &thd->lex->select_lex);
   thd->abort_on_warning= 0;
   DBUG_RETURN(TRUE);
 }

--- 1.168/sql/sql_lex.cc	2005-12-06 22:28:11 -08:00
+++ 1.169/sql/sql_lex.cc	2005-12-12 11:55:13 -08:00
@@ -184,6 +184,9 @@
   lex->sroutines_list.empty();
   lex->sroutines_list_own_last= lex->sroutines_list.next;
   lex->sroutines_list_own_elements= 0;
+  lex->nest_level=0 ;
+  lex->allow_sum_func= 0;
+  lex->in_sum_func= NULL;
   DBUG_VOID_RETURN;
 }
 
@@ -1147,6 +1150,7 @@
   first_cond_optimization= 1;
   parsing_place= NO_MATTER;
   exclude_from_table_unique_test= no_wrap_view_item= FALSE;
+  nest_level= 0;
   link_next= 0;
 }
 
@@ -1166,6 +1170,7 @@
   interval_list.empty();
   use_index.empty();
   ftfunc_list_alloc.empty();
+  inner_sum_func_list= 0;
   ftfunc_list= &ftfunc_list_alloc;
   linkage= UNSPECIFIED_TYPE;
   order_list.elements= 0;

--- 1.209/sql/sql_lex.h	2005-12-06 22:28:12 -08:00
+++ 1.210/sql/sql_lex.h	2005-12-12 11:55:13 -08:00
@@ -531,6 +531,8 @@
   ulong table_join_options;
   uint in_sum_expr;
   uint select_number; /* number of select (used for EXPLAIN) */
+  int nest_level;     /* nesting level of select */
+  Item_sum *inner_sum_func_list; /* list of sum func in nested selects */ 
   uint with_wild; /* item list contain '*' */
   bool  braces;   	/* SELECT ... UNION (SELECT ... ) <- this braces */
   /* TRUE when having fix field called in processing of this SELECT */
@@ -794,12 +796,23 @@
 
   SQL_LIST	      proc_list, auxilliary_table_list, save_list;
   create_field	      *last_field;
+  Item_sum *in_sum_func;
   udf_func udf;
   HA_CHECK_OPT   check_opt;			// check/repair options
   HA_CREATE_INFO create_info;
   LEX_MASTER_INFO mi;				// used by CHANGE MASTER
   USER_RESOURCES mqh;
   ulong type;
+  /*
+    This variable is used in post-parse stage to declare that sum-functions,
+    or functions which have sense only if GROUP BY is present, are allowed.
+    For example in a query
+    SELECT ... FROM ...WHERE MIN(i) == 1 GROUP BY ... HAVING MIN(i) > 2
+    MIN(i) in the WHERE clause is not allowed in the opposite to MIN(i)
+    in the HAVING clause. Due to possible nesting of select construct
+    the variable can contain 0 or 1 for each nest level.
+  */
+  nesting_map allow_sum_func;
   enum_sql_command sql_command, orig_sql_command;
   thr_lock_type lock_option;
   enum SSL_type ssl_type;			/* defined in violite.h */
@@ -818,6 +831,7 @@
   uint grant, grant_tot_col, which_columns;
   uint fk_delete_opt, fk_update_opt, fk_match_option;
   uint slave_thd_opt, start_transaction_opt;
+  int nest_level;
   /*
     In LEX representing update which were transformed to multi-update
     stores total number of tables. For LEX representing multi-delete

--- 1.496/sql/sql_parse.cc	2005-12-12 03:59:06 -08:00
+++ 1.497/sql/sql_parse.cc	2005-12-12 11:55:13 -08:00
@@ -5428,6 +5428,8 @@
   select_lex->parent_lex= lex; /* Used in init_query. */
   select_lex->init_query();
   select_lex->init_select();
+  lex->nest_level++;
+  select_lex->nest_level= lex->nest_level;
   /*
     Don't evaluate this subquery during statement prepare even if
     it's a constant one. The flag is switched off in the end of

--- 1.374/sql/sql_select.cc	2005-12-12 02:29:42 -08:00
+++ 1.375/sql/sql_select.cc	2005-12-12 11:55:13 -08:00
@@ -274,21 +274,20 @@
 			       ORDER *order,
 			       ORDER *group, bool *hidden_group_fields)
 {
-  bool save_allow_sum_func;
   int res;
+  nesting_map save_allow_sum_func=thd->lex->allow_sum_func ;
   DBUG_ENTER("setup_without_group");
 
-  save_allow_sum_func= thd->allow_sum_func;
-  thd->allow_sum_func= 0;
+  thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level);
   res= setup_conds(thd, tables, leaves, conds);
 
-  thd->allow_sum_func= save_allow_sum_func;
+  thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
   res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields,
                           order);
-  thd->allow_sum_func= 0;
+  thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level);
   res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields,
                           group, hidden_group_fields);
-  thd->allow_sum_func= save_allow_sum_func;
+  thd->lex->allow_sum_func= save_allow_sum_func;
   DBUG_RETURN(res);
 }
 
@@ -355,8 +354,9 @@
   
   if (having)
   {
+    nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
     thd->where="having clause";
-    thd->allow_sum_func=1;
+    thd->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
     select_lex->having_fix_field= 1;
     bool having_fix_rc= (!having->fixed &&
 			 (having->fix_fields(thd, &having) ||
@@ -366,6 +366,18 @@
       DBUG_RETURN(-1);				/* purecov: inspected */
     if (having->with_sum_func)
       having->split_sum_func(thd, ref_pointer_array, all_fields);
+    thd->lex->allow_sum_func= save_allow_sum_func;
+  }
+  if (select_lex->inner_sum_func_list)
+  {
+    Item_sum *end=select_lex->inner_sum_func_list;
+    Item_sum *item_sum= end;  
+    do
+    { 
+      item_sum= item_sum->next;
+      item_sum->split_sum_func2(thd, ref_pointer_array,
+                                all_fields, item_sum->ref_by, FALSE);
+    } while (item_sum != end);
   }
 
   if (!thd->lex->view_prepare_mode)
@@ -5231,7 +5243,9 @@
         join->const_table_map|=RAND_TABLE_BIT;
       {						// Check const tables
         COND *const_cond=
-	  make_cond_for_table(cond,join->const_table_map,(table_map) 0);
+	  make_cond_for_table(cond,
+                              join->const_table_map,
+                              (table_map) 0);
         DBUG_EXECUTE("where",print_where(const_cond,"constants"););
         for (JOIN_TAB *tab= join->join_tab+join->const_tables;
              tab < join->join_tab+join->tables ; tab++)

--- 1.178/sql/sql_update.cc	2005-12-02 11:07:08 -08:00
+++ 1.179/sql/sql_update.cc	2005-12-12 11:55:14 -08:00
@@ -632,6 +632,7 @@
     if (!transactional_table)
       thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
   }
+  free_underlaid_joins(thd, select_lex);
   if (transactional_table)
   {
     if (ha_autocommit_or_rollback(thd, error >= 0))
@@ -644,7 +645,6 @@
     thd->lock=0;
   }
 
-  free_underlaid_joins(thd, select_lex);
   if (error < 0)
   {
     char buff[STRING_BUFFER_USUAL_SIZE];
@@ -706,7 +706,7 @@
   bzero((char*) &tables,sizeof(tables));	// For ORDER BY
   tables.table= table;
   tables.alias= table_list->alias;
-  thd->allow_sum_func= 0;
+  thd->lex->allow_sum_func= 0;
 
   if (setup_tables(thd, &select_lex->context, &select_lex->top_join_list,
                    table_list, conds, &select_lex->leaf_tables,

--- 1.429/sql/sql_yacc.yy	2005-12-09 03:39:41 -08:00
+++ 1.430/sql/sql_yacc.yy	2005-12-12 11:55:14 -08:00
@@ -5061,7 +5061,7 @@
 	    }
 	    $$= new Item_default_value(Lex->current_context(), $3);
 	  }
-	| VALUES '(' simple_ident ')'
+	| VALUES '(' simple_ident_nospvar ')'
 	  { $$= new Item_insert_value(Lex->current_context(), $3); }
 	| FUNC_ARG0 '(' ')'
 	  {
@@ -9549,6 +9549,7 @@
 	  LEX *lex=Lex;
           lex->pop_context();
 	  lex->current_select = lex->current_select->return_after_parsing();
+          lex->nest_level--;
 	};
 
 definer:

--- 1.120/sql/item_subselect.cc	2005-11-23 12:47:27 -08:00
+++ 1.121/sql/item_subselect.cc	2005-12-12 11:55:12 -08:00
@@ -806,6 +806,7 @@
 	!(select_lex->next_select()))
     {
       Item_sum_hybrid *item;
+      nesting_map save_allow_sum_func;
       if (func->l_op())
       {
 	/*
@@ -831,6 +832,8 @@
 	it.replace(item);
       }
 
+      save_allow_sum_func= thd->lex->allow_sum_func;
+      thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
       /*
 	Item_sum_(max|min) can't substitute other item => we can use 0 as
         reference, also Item_sum_(max|min) can't be fixed after creation, so
@@ -838,6 +841,7 @@
       */
       if (item->fix_fields(thd, 0))
 	DBUG_RETURN(RES_ERROR);
+      thd->lex->allow_sum_func= save_allow_sum_func; 
       /* we added aggregate function => we have to change statistic */
       count_field_types(&join->tmp_table_param, join->all_fields, 0);
 

--- 1.175/mysql-test/r/sp.result	2005-12-12 03:30:11 -08:00
+++ 1.176/mysql-test/r/sp.result	2005-12-12 11:55:12 -08:00
@@ -4110,23 +4110,23 @@
 x
 4711
 drop procedure bug14376|
-drop procedure if exists p1|
-drop table if exists t1|
-create table t1 (a varchar(255))|
-insert into t1 (a) values ("a - table column")|
-create procedure p1(a varchar(255))
+drop procedure if exists bug5967|
+drop table if exists t3|
+create table t3 (a varchar(255))|
+insert into t3 (a) values ("a - table column")|
+create procedure bug5967(a varchar(255))
 begin
 declare i varchar(255);
-declare c cursor for select a from t1;
+declare c cursor for select a from t3;
 select a;
-select a from t1 into i;
+select a from t3 into i;
 select i as 'Parameter takes precedence over table column';                     open c;
 fetch c into i;
 close c;
 select i as 'Parameter takes precedence over table column in cursors';
 begin
 declare a varchar(255) default 'a - local variable';
-declare c1 cursor for select a from t1;
+declare c1 cursor for select a from t3;
 select a as 'A local variable takes precedence over parameter';
 open c1;
 fetch c1 into i;
@@ -4134,9 +4134,9 @@
 select i as 'A local variable takes precedence over parameter in cursors';
 begin
 declare a varchar(255) default 'a - local variable in a nested compound statement';
-declare c2 cursor for select a from t1;
+declare c2 cursor for select a from t3;
 select a as 'A local variable in a nested compound statement takes precedence over a local variable in the outer statement';
-select a from t1 into i;
+select a from t3 into i;
 select i as  'A local variable in a nested compound statement takes precedence over table column';
 open c2;
 fetch c2 into i;
@@ -4145,7 +4145,7 @@
 end;
 end;
 end|
-call p1("a - stored procedure parameter")|
+call bug5967("a - stored procedure parameter")|
 a
 a - stored procedure parameter
 Parameter takes precedence over table column
@@ -4162,7 +4162,7 @@
 a - local variable in a nested compound statement
 A local variable in a nested compound statement takes precedence over table column in cursors
 a - local variable in a nested compound statement
-drop procedure p1|
+drop procedure bug5967|
 drop procedure if exists bug13012|
 create procedure bug13012()
 BEGIN
@@ -4190,17 +4190,17 @@
 Table	Op	Msg_type	Msg_text
 test.t1	repair	status	OK
 test.t2	repair	status	OK
-test.t3	repair	error	Table 'test.t3' doesn't exist
+test.t3	repair	status	OK
 test.v1	repair	error	'test.v1' is not BASE TABLE
 Table	Op	Msg_type	Msg_text
 test.t1	optimize	status	OK
 test.t2	optimize	status	OK
-test.t3	optimize	error	Table 'test.t3' doesn't exist
+test.t3	optimize	status	OK
 test.v1	optimize	error	'test.v1' is not BASE TABLE
 Table	Op	Msg_type	Msg_text
 test.t1	analyze	status	Table is already up to date
 test.t2	analyze	status	Table is already up to date
-test.t3	analyze	error	Table 'test.t3' doesn't exist
+test.t3	analyze	status	Table is already up to date
 test.v1	analyze	error	'test.v1' is not BASE TABLE
 Warnings:
 Error	1146	Table 'test.t3' doesn't exist
@@ -4213,17 +4213,17 @@
 Table	Op	Msg_type	Msg_text
 test.t1	repair	status	OK
 test.t2	repair	status	OK
-test.t3	repair	error	Table 'test.t3' doesn't exist
+test.t3	repair	status	OK
 test.v1	repair	error	'test.v1' is not BASE TABLE
 Table	Op	Msg_type	Msg_text
 test.t1	optimize	status	OK
 test.t2	optimize	status	OK
-test.t3	optimize	error	Table 'test.t3' doesn't exist
+test.t3	optimize	status	OK
 test.v1	optimize	error	'test.v1' is not BASE TABLE
 Table	Op	Msg_type	Msg_text
 test.t1	analyze	status	Table is already up to date
 test.t2	analyze	status	Table is already up to date
-test.t3	analyze	error	Table 'test.t3' doesn't exist
+test.t3	analyze	status	Table is already up to date
 test.v1	analyze	error	'test.v1' is not BASE TABLE
 Warnings:
 Error	1146	Table 'test.t3' doesn't exist
@@ -4236,17 +4236,17 @@
 Table	Op	Msg_type	Msg_text
 test.t1	repair	status	OK
 test.t2	repair	status	OK
-test.t3	repair	error	Table 'test.t3' doesn't exist
+test.t3	repair	status	OK
 test.v1	repair	error	'test.v1' is not BASE TABLE
 Table	Op	Msg_type	Msg_text
 test.t1	optimize	status	OK
 test.t2	optimize	status	OK
-test.t3	optimize	error	Table 'test.t3' doesn't exist
+test.t3	optimize	status	OK
 test.v1	optimize	error	'test.v1' is not BASE TABLE
 Table	Op	Msg_type	Msg_text
 test.t1	analyze	status	Table is already up to date
 test.t2	analyze	status	Table is already up to date
-test.t3	analyze	error	Table 'test.t3' doesn't exist
+test.t3	analyze	status	Table is already up to date
 test.v1	analyze	error	'test.v1' is not BASE TABLE
 Warnings:
 Error	1146	Table 'test.t3' doesn't exist
@@ -4258,8 +4258,17 @@
 drop procedure bug13012|
 drop view v1;
 select * from t1|
-a
-a - table column
+id	data
+aa	0
+aa	1
+aa	2
+aa	3
+aa	4
+aa	5
+aa	6
+aa	7
+aa	8
+aa	9
 drop schema if exists mysqltest1|
 Warnings:
 Note	1008	Can't drop database 'mysqltest1'; database doesn't exist
@@ -4299,4 +4308,31 @@
 drop schema if exists mysqltest2|
 drop schema if exists mysqltest3|
 use test|
+drop table if exists t3|
+drop procedure if exists bug15441|
+create table t3 (id int not null primary key, county varchar(25))|
+insert into t3 (id, county) values (1, 'York')|
+create procedure bug15441(c varchar(25))
+begin
+update t3 set id=2, county=values(c);
+end|
+call bug15441('county')|
+ERROR 42S22: Unknown column 'c' in 'field list'
+drop procedure bug15441|
+create procedure bug15441(county varchar(25))
+begin
+declare c varchar(25) default "hello";
+insert into t3 (id, county) values (1, county)
+on duplicate key update county= values(county);
+select * from t3;
+update t3 set id=2, county=values(id);
+select * from t3;
+end|
+call bug15441('Yale')|
+id	county
+1	Yale
+id	county
+2	NULL
+drop table t3|
+drop procedure bug15441|
 drop table t1,t2;

--- 1.156/sql/sql_prepare.cc	2005-11-23 04:04:13 -08:00
+++ 1.157/sql/sql_prepare.cc	2005-12-12 11:55:13 -08:00
@@ -2131,7 +2131,8 @@
     lex->result->cleanup();
     lex->result->set_thd(thd);
   }
-  thd->allow_sum_func= 0;
+  lex->allow_sum_func= 0;
+  lex->in_sum_func= NULL;
   DBUG_VOID_RETURN;  
 }
 
Thread
bk commit into 5.1 tree (jimw:1.1958)Jim Winstead12 Dec