[Commits] 696ccae4d4205a8b4b2d9936280ecd03a458c105 Merge branch '10.2-mdev9197-cons' of github.com:shagalla/server into 10.2

Igor Babaev igor at askmonty.org
Thu Sep 1 02:10:28 EEST 2016


commit 696ccae4d4205a8b4b2d9936280ecd03a458c105
Merge: 670760d eb2c147
Author: Igor Babaev <igor at askmonty.org>
Commit: Igor Babaev <igor at askmonty.org>

    Merge branch '10.2-mdev9197-cons' of github.com:shagalla/server into 10.2

 mysql-test/r/derived_cond_pushdown.result | 6436 +++++++++++++++++++++++++++++
 mysql-test/t/derived_cond_pushdown.test   |  812 ++++
 sql/item.cc                               |  204 +
 sql/item.h                                |  121 +-
 sql/item_cmpfunc.cc                       |   40 +
 sql/item_cmpfunc.h                        |  104 +-
 sql/item_func.cc                          |    3 +
 sql/item_func.h                           |  158 +
 sql/item_geofunc.h                        |   69 +
 sql/item_inetfunc.h                       |   16 +
 sql/item_row.cc                           |   18 +
 sql/item_row.h                            |    3 +
 sql/item_strfunc.h                        |  139 +-
 sql/item_subselect.h                      |    3 +
 sql/item_sum.h                            |   38 +
 sql/item_timefunc.h                       |   92 +-
 sql/item_windowfunc.h                     |   17 +-
 sql/item_xmlfunc.cc                       |   34 +
 sql/item_xmlfunc.h                        |    4 +
 sql/procedure.h                           |    1 +
 sql/sql_derived.cc                        |  134 +
 sql/sql_derived.h                         |    8 +
 sql/sql_lex.cc                            |  188 +
 sql/sql_lex.h                             |   24 +-
 sql/sql_priv.h                            |    4 +-
 sql/sql_select.cc                         |   89 +-
 sql/sql_select.h                          |    2 +-
 sql/sys_vars.cc                           |    1 +
 sql/table.cc                              |  176 +
 sql/table.h                               |    2 +
 30 files changed, 8926 insertions(+), 14 deletions(-)

diff --cc sql/item.cc
index 5da95b0,6c24cf2..6bce98b
--- a/sql/item.cc
+++ b/sql/item.cc
@@@ -6708,10 -6622,88 +6776,89 @@@ Item *Item_field::update_value_transfor
  }
  
  
+ Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg)
+ {
+   st_select_lex *sl= (st_select_lex *)arg;
+   table_map map= sl->master_unit()->derived->table->map;
+   if (!((Item_field*)this)->item_equal)
+   {
+     if (used_tables() == map)
+     {
+       Item_ref *rf= 
+ 	new (thd->mem_root) Item_ref(thd, &sl->context, 
+ 	  	   	             NullS, NullS,
+ 				   ((Item_field*) this)->field_name);
+       if (!rf)
+ 	return 0;
+       return rf;
+     }
+   }
+   else
+   {
+     Item_equal *cond= (Item_equal *) ((Item_field*)this)->item_equal;
+     Item_equal_fields_iterator li(*cond);
+     Item *item;
+     while ((item=li++))
+     {
+       if (item->used_tables() == map && item->type() == FIELD_ITEM)
+       {
+ 	Item_ref *rf= 
+ 	  new (thd->mem_root) Item_ref(thd, &sl->context, 
+ 				       NullS, NullS,
+ 				     ((Item_field*) item)->field_name);
+ 	if (!rf)
+ 	  return 0;
+ 	return rf;
+       }
+     }
+   }
+   return this;
+ }
+ 
+ 
+ Item *Item_field::derived_field_transformer_for_where(THD *thd, uchar *arg)
+ {
+   st_select_lex *sl= (st_select_lex *)arg;
+   List_iterator<Grouping_tmp_field> li(sl->grouping_tmp_fields);
+   Grouping_tmp_field *field;
+   table_map map= sl->master_unit()->derived->table->map;
+   if (used_tables() == map)
+   {
+     while ((field=li++))
+     {
+       if (((Item_field*) this)->field == field->tmp_field)
+ 	return field->producing_item->build_clone(thd, thd->mem_root);
+     }
+   }
+   else if (((Item_field*)this)->item_equal)
+   {
+     Item_equal *cond= (Item_equal *) ((Item_field*)this)->item_equal;
+     Item_equal_fields_iterator it(*cond);
+     Item *item;
+     while ((item=it++))
+     {
+       if (item->used_tables() == map && item->type() == FIELD_ITEM)
+       {   
+ 	Item_field *field_item= (Item_field *) item;
+ 	li.rewind();
+         while ((field=li++))
+         {
+ 	  if (field_item->field == field->tmp_field)
+ 	  {
+ 	    return field->producing_item->build_clone(thd, thd->mem_root);
+ 	  }
+         }  
+       }
+     }
+   }
+   return this;
+ }
+ 
+ 
  void Item_field::print(String *str, enum_query_type query_type)
  {
 -  if (field && field->table->const_table)
 +  if (field && field->table->const_table &&
 +      !(query_type & QT_NO_DATA_EXPANSION))
    {
      print_value(str);
      return;
diff --cc sql/item.h
index 8fcbf82,0cbe30c..34fd667
--- a/sql/item.h
+++ b/sql/item.h
@@@ -32,6 -32,29 +32,8 @@@ C_MODE_STAR
  #include <ma_dyncol.h>
  C_MODE_END
  
 -#ifndef DBUG_OFF
+ const char *dbug_print_item(Item *item);
+ 
 -static inline
 -bool trace_unsupported_func(const char *where, const char *processor_name)
 -{
 -  char buff[64];                                                         
 -  sprintf(buff, "%s::%s", where, processor_name);
 -  DBUG_ENTER(buff);
 -  sprintf(buff, "%s returns TRUE: unsupported function", processor_name);
 -  DBUG_PRINT("info", ("%s", buff));
 -  DBUG_RETURN(TRUE);
 -}
 -#else
 -#define trace_unsupported_func(X,Y) TRUE
 -#endif
 -
 -static inline
 -bool trace_unsupported_by_check_vcol_func_processor(const char *where)
 -{
 -  return trace_unsupported_func(where, "check_vcol_func_processor");
 -}
 -
  class Protocol;
  struct TABLE_LIST;
  void item_init(void);			/* Init item functions */
@@@ -1110,9 -1110,10 +1115,10 @@@ public
    virtual bool basic_const_item() const { return 0; }
    /* cloning of constant items (0 if it is not const) */
    virtual Item *clone_item(THD *thd) { return 0; }
+   virtual Item* build_clone(THD *thd, MEM_ROOT *mem_root) { return get_copy(thd, mem_root); }
    virtual cond_result eq_cmp_result() const { return COND_OK; }
    inline uint float_length(uint decimals_par) const
 -  { return decimals != NOT_FIXED_DEC ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
 +  { return decimals < FLOATING_POINT_DECIMALS ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
    /* Returns total number of decimal digits */
    virtual uint decimal_precision() const;
    /* Returns the number of integer part digits only */
@@@ -1472,9 -1476,17 +1478,17 @@@
    {
      return FALSE;
    }
 -  virtual bool exists2in_processor(uchar *opt_arg) { return 0; }
 -  virtual bool find_selective_predicates_list_processor(uchar *opt_arg)
 +  virtual bool exists2in_processor(void *opt_arg) { return 0; }
 +  virtual bool find_selective_predicates_list_processor(void *opt_arg)
    { return 0; }
+   virtual bool exclusive_dependence_on_table_processor(uchar *map)
+   { return 0; }
+   virtual bool exclusive_dependence_on_grouping_fields_processor(uchar *arg)
+  { return 0; }
+   //virtual Item *get_copy(THD *thd, MEM_ROOT *mem_root);
+   
+ 
+   virtual Item *get_copy(THD *thd, MEM_ROOT *mem_root)=0;
  
    /* To call bool function for all arguments */
    struct bool_func_call_args
@@@ -2241,10 -2281,12 +2288,12 @@@ public
    {
      return value_item->send(protocol, str);
    }
 -  bool check_vcol_func_processor(uchar *arg) 
 +  bool check_vcol_func_processor(void *arg) 
    {
 -    return trace_unsupported_by_check_vcol_func_processor("name_const");
 +    return mark_unsupported_function("name_const()", arg, VCOL_IMPOSSIBLE);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_name_const>(thd, mem_root, this); }
  };
  
  class Item_num: public Item_basic_constant
@@@ -2621,7 -2668,10 +2678,9 @@@ public
    }
  
    Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs);
 -  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
 -  bool check_vcol_func_processor(uchar *arg) { return FALSE;}
 +  bool check_partition_func_processor(void *int_arg) {return FALSE;}
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_null>(thd, mem_root, this); }
  };
  
  class Item_null_result :public Item_null
@@@ -2782,7 -2832,9 +2841,9 @@@ public
    { return this; }
  
    bool append_for_log(THD *thd, String *str);
 -  
 +  bool check_vcol_func_processor(void *int_arg) {return FALSE;}
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
+ 
  private:
    virtual bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
  
@@@ -2831,6 -2883,10 +2892,8 @@@ public
    { return (uint) (max_length - MY_TEST(value < 0)); }
    bool eq(const Item *item, bool binary_cmp) const
    { return int_eq(value, item); }
 -  bool check_partition_func_processor(uchar *bool_arg) { return FALSE;}
 -  bool check_vcol_func_processor(uchar *arg) { return FALSE;}
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_int>(thd, mem_root, this); }
  };
  
  
@@@ -2845,8 -2901,10 +2908,10 @@@ public
    String *val_str(String*);
    Item *clone_item(THD *thd);
    virtual void print(String *str, enum_query_type query_type);
 -  Item_num *neg(THD *thd);
 +  Item *neg(THD *thd);
    uint decimal_precision() const { return max_length; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_uint>(thd, mem_root, this); }
  };
  
  
@@@ -2893,6 -2956,10 +2958,8 @@@ public
    uint decimal_precision() const { return decimal_value.precision(); }
    bool eq(const Item *, bool binary_cmp) const;
    void set_decimal_value(my_decimal *value_par);
 -  bool check_partition_func_processor(uchar *bool_arg) { return FALSE;}
 -  bool check_vcol_func_processor(uchar *arg) { return FALSE;}
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_decimal>(thd, mem_root, this); }
  };
  
  
@@@ -4259,12 -4351,15 +4348,15 @@@ public
        orig_item->bring_value();
    }
    virtual bool is_expensive() { return orig_item->is_expensive(); }
 -  bool is_expensive_processor(uchar *arg)
 +  bool is_expensive_processor(void *arg)
    { return orig_item->is_expensive_processor(arg); }
 -  bool check_vcol_func_processor(uchar *arg)
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor("cache");
 +    return mark_unsupported_function("cache", arg, VCOL_IMPOSSIBLE);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_cache_wrapper>(thd, mem_root, this); }
+   Item *build_clone(THD *thd, MEM_ROOT *mem_root) { return 0; }
  };
  
  
diff --cc sql/item_cmpfunc.h
index f899775,3d68822..6d432bd
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@@ -980,8 -1032,10 +1033,10 @@@ public
      return Item_func_case_abbreviation2::decimal_precision2(args + 1);
    }
    const char *func_name() const { return "if"; }
 -  bool eval_not_null_tables(uchar *opt_arg);
 +  bool eval_not_null_tables(void *opt_arg);
    void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_if>(thd, mem_root, this); }
  private:
    void cache_type_info(Item *source);
  };
@@@ -1045,18 -1097,13 +1100,20 @@@ public
                                                           cond, &args[0]);
      args[1]->propagate_equal_fields_and_change_item_tree(thd, cmpctx,
                                                           cond, &args[1]);
 -    args[2]->propagate_equal_fields_and_change_item_tree(thd,
 -                                                         Context_identity(),
 -                                                         cond, &args[2]);
 +    /*
 +      MDEV-9712 Performance degradation of nested NULLIF
 +      ANY_SUBST is more relaxed than IDENTITY_SUBST.
 +      If ANY_SUBST did not change args[0],
 +      then we can skip propagation for args[2].
 +    */
 +    if (old0 != args[0])
 +      args[2]->propagate_equal_fields_and_change_item_tree(thd,
 +                                                           Context_identity(),
 +                                                           cond, &args[2]);
      return this;
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_nullif>(thd, mem_root, this); }
  };
  
  
@@@ -1498,7 -1544,19 +1554,20 @@@ public
    CHARSET_INFO *compare_collation() const { return cmp_collation.collation; }
    void cleanup();
    Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond);
 +  bool need_parentheses_in_default() { return true; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_case>(thd, mem_root, this); }
+   Item *build_clone(THD *thd, MEM_ROOT *mem_root)
+   {
+     Item_func_case *clone= (Item_func_case *) Item_func::build_clone(thd, mem_root);
+     if (clone)
+     {
+       clone->case_item= 0;
+       clone->arg_buffer= 0;
+       bzero(&clone->cmp_items, sizeof(cmp_items));
+     }
+     return clone;
+   } 
  };
  
  /*
@@@ -1592,9 -1650,21 +1661,21 @@@ public
    virtual void print(String *str, enum_query_type query_type);
    enum Functype functype() const { return IN_FUNC; }
    const char *func_name() const { return " IN "; }
 -  bool eval_not_null_tables(uchar *opt_arg);
 +  bool eval_not_null_tables(void *opt_arg);
    void fix_after_pullout(st_select_lex *new_parent, Item **ref);
 -  bool count_sargable_conds(uchar *arg);
 +  bool count_sargable_conds(void *arg);
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_in>(thd, mem_root, this); }
+   Item *build_clone(THD *thd, MEM_ROOT *mem_root)
+   {
+     Item_func_in *clone= (Item_func_in *) Item_func::build_clone(thd, mem_root);
+     if (clone)
+     {
+       clone->array= 0;
+       bzero(&clone->cmp_items, sizeof(cmp_items));
+     }
+     return clone;
+   }      
  };
  
  class cmp_item_row :public cmp_item
@@@ -1872,7 -1946,10 +1957,10 @@@ public
    }
    void cleanup();
  
 -  bool find_selective_predicates_list_processor(uchar *arg);
 +  bool find_selective_predicates_list_processor(void *arg);
+   
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_like>(thd, mem_root, this); }
  };
  
  
@@@ -2081,7 -2162,8 +2173,8 @@@ public
    Item* propagate_equal_fields(THD *, const Context &, COND_EQUAL *);
    Item *compile(THD *thd, Item_analyzer analyzer, uchar **arg_p,
                  Item_transformer transformer, uchar *arg_t);
 -  bool eval_not_null_tables(uchar *opt_arg);
 +  bool eval_not_null_tables(void *opt_arg);
+   Item *build_clone(THD *thd, MEM_ROOT *mem_root);
  };
  
  template <template<class> class LI, class T> class Item_equal_iterator;
@@@ -2254,8 -2336,9 +2347,9 @@@ public
  
    void set_context_field(Item_field *ctx_field) { context_field= ctx_field; }
    void set_link_equal_fields(bool flag) { link_equal_fields= flag; }
+   Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
    friend class Item_equal_fields_iterator;
 -  bool count_sargable_conds(uchar *arg);
 +  bool count_sargable_conds(void *arg);
    friend class Item_equal_iterator<List_iterator_fast,Item>;
    friend class Item_equal_iterator<List_iterator,Item>;
    friend Item *eliminate_item_equal(THD *thd, COND *cond,
@@@ -2430,7 -2518,8 +2528,9 @@@ public
    Item_func_dyncol_check(THD *thd, Item *str): Item_bool_func(thd, str) {}
    longlong val_int();
    const char *func_name() const { return "column_check"; }
 +  bool need_parentheses_in_default() { return false; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_dyncol_check>(thd, mem_root, this); }
  };
  
  class Item_func_dyncol_exists :public Item_bool_func
@@@ -2440,7 -2529,8 +2540,9 @@@ public
      Item_bool_func(thd, str, num) {}
    longlong val_int();
    const char *func_name() const { return "column_exists"; }
 +  bool need_parentheses_in_default() { return false; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_dyncol_exists>(thd, mem_root, this); }
  };
  
  inline bool is_cond_or(Item *item)
diff --cc sql/item_func.h
index 92bc798,9cd5aea..44ad4e8
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@@ -611,10 -612,9 +611,12 @@@ public
    void fix_length_and_dec();
    bool fix_fields(THD *thd, Item **ref);
    longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
 -  bool check_vcol_func_processor(uchar *int_arg) { return TRUE;}
 +  bool check_vcol_func_processor(void *arg)
 +  {
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC);
 +  }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_connection_id>(thd, mem_root, this); }
  };
  
  
@@@ -639,7 -635,8 +641,9 @@@ public
    }
    virtual void print(String *str, enum_query_type query_type);
    uint decimal_precision() const { return args[0]->decimal_precision(); }
 +  bool need_parentheses_in_default() { return true; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_signed>(thd, mem_root, this); }
  };
  
  
@@@ -651,13 -648,10 +655,15 @@@ public
      unsigned_flag= 1;
    }
    const char *func_name() const { return "cast_as_unsigned"; }
 -  longlong val_int();
 +  longlong val_int()
 +  {
 +    longlong value= args[0]->val_int_unsigned_typecast();
 +    null_value= args[0]->null_value;
 +    return value;
 +  }
    virtual void print(String *str, enum_query_type query_type);
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_unsigned>(thd, mem_root, this); }
  };
  
  
@@@ -681,7 -675,8 +687,9 @@@ public
    void fix_length_and_dec() {}
    const char *func_name() const { return "decimal_typecast"; }
    virtual void print(String *str, enum_query_type query_type);
 +  bool need_parentheses_in_default() { return true; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_decimal_typecast>(thd, mem_root, this); }
  };
  
  
@@@ -699,7 -694,8 +707,9 @@@ public
    void fix_length_and_dec() { maybe_null= 1; }
    const char *func_name() const { return "double_typecast"; }
    virtual void print(String *str, enum_query_type query_type);
 +  bool need_parentheses_in_default() { return true; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_double_typecast>(thd, mem_root, this); }
  };
  
  
@@@ -748,8 -748,10 +762,10 @@@ public
    double real_op();
    my_decimal *decimal_op(my_decimal *);
    void result_precision();
 -  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
 -  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 +  bool check_partition_func_processor(void *int_arg) {return FALSE;}
 +  bool check_vcol_func_processor(void *arg) { return FALSE;}
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_mul>(thd, mem_root, this); }
  };
  
  
@@@ -781,9 -785,10 +799,11 @@@ public
      print_op(str, query_type);
    }
  
 -  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
 -  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 +  bool check_partition_func_processor(void *int_arg) {return FALSE;}
 +  bool check_vcol_func_processor(void *arg) { return FALSE;}
 +  bool need_parentheses_in_default() { return true; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_int_div>(thd, mem_root, this); }
  };
  
  
@@@ -797,8 -802,10 +817,10 @@@ public
    const char *func_name() const { return "%"; }
    void result_precision();
    void fix_length_and_dec();
 -  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
 -  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 +  bool check_partition_func_processor(void *int_arg) {return FALSE;}
 +  bool check_vcol_func_processor(void *arg) { return FALSE;}
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_mod>(thd, mem_root, this); }
  };
  
  
@@@ -813,9 -820,10 +835,11 @@@ public
    enum Functype functype() const   { return NEG_FUNC; }
    void fix_length_and_dec();
    uint decimal_precision() const { return args[0]->decimal_precision(); }
 -  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
 -  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 +  bool check_partition_func_processor(void *int_arg) {return FALSE;}
 +  bool check_vcol_func_processor(void *arg) { return FALSE;}
 +  bool need_parentheses_in_default() { return true; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_neg>(thd, mem_root, this); }
  };
  
  
@@@ -828,8 -836,10 +852,10 @@@ public
    my_decimal *decimal_op(my_decimal *);
    const char *func_name() const { return "abs"; }
    void fix_length_and_dec();
 -  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
 -  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 +  bool check_partition_func_processor(void *int_arg) {return FALSE;}
 +  bool check_vcol_func_processor(void *arg) { return FALSE;}
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_abs>(thd, mem_root, this); }
  };
  
  // A class to handle logarithmic and trigonometric functions
@@@ -991,8 -1029,10 +1045,10 @@@ public
    longlong int_op();
    double real_op();
    my_decimal *decimal_op(my_decimal *);
 -  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
 -  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 +  bool check_partition_func_processor(void *int_arg) {return FALSE;}
 +  bool check_vcol_func_processor(void *arg) { return FALSE;}
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_ceiling>(thd, mem_root, this); }
  };
  
  
@@@ -1004,8 -1044,10 +1060,10 @@@ public
    longlong int_op();
    double real_op();
    my_decimal *decimal_op(my_decimal *);
 -  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
 -  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 +  bool check_partition_func_processor(void *int_arg) {return FALSE;}
 +  bool check_vcol_func_processor(void *arg) { return FALSE;}
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_floor>(thd, mem_root, this); }
  };
  
  /* This handles round and truncate */
@@@ -1038,10 -1082,12 +1098,12 @@@ public
    void update_used_tables();
    bool fix_fields(THD *thd, Item **ref);
    void cleanup() { first_eval= TRUE; Item_real_func::cleanup(); }
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_rand>(thd, mem_root, this); }
  private:
    void seed_random (Item * val);  
  };
@@@ -1334,10 -1419,12 +1436,12 @@@ public
      unsigned_flag=1;
    }
    bool fix_fields(THD *thd, Item **ref);
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_last_insert_id>(thd, mem_root, this); }
  };
  
  
@@@ -1351,10 -1438,12 +1455,12 @@@ public
    const char *func_name() const { return "benchmark"; }
    void fix_length_and_dec() { max_length=1; maybe_null=0; }
    virtual void print(String *str, enum_query_type query_type);
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_benchmark>(thd, mem_root, this); }
  };
  
  
@@@ -1373,10 -1462,12 +1479,12 @@@ public
    }
    bool is_expensive() { return 1; }
    longlong val_int();
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_sleep>(thd, mem_root, this); }
  };
  
  
@@@ -1643,10 -1738,12 +1759,12 @@@ class Item_func_get_lock :public Item_i
    }
    bool const_item() const { return 0; }
    bool is_expensive() { return 1; }
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_get_lock>(thd, mem_root, this); }
  };
  
  class Item_func_release_lock :public Item_int_func
@@@ -1663,10 -1760,12 +1781,12 @@@ public
    }
    bool const_item() const { return 0; }
    bool is_expensive() { return 1; }
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_release_lock>(thd, mem_root, this); }
  };
  
  /* replication functions */
@@@ -1683,10 -1782,12 +1803,12 @@@ public
    longlong val_int();
    const char *func_name() const { return "master_pos_wait"; }
    void fix_length_and_dec() { max_length=21; maybe_null=1;}
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_master_pos_wait>(thd, mem_root, this); }
  };
  
  
@@@ -1699,10 -1800,12 +1821,12 @@@ public
    longlong val_int();
    const char *func_name() const { return "master_gtid_wait"; }
    void fix_length_and_dec() { max_length=10+1+10+1+20+1; maybe_null=0;}
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_master_gtid_wait>(thd, mem_root, this); }
  };
  
  
@@@ -1812,10 -1915,12 +1936,12 @@@ public
    void save_org_in_field(Field *field,
                           fast_field_copier data __attribute__ ((__unused__)))
      { (void)save_in_field(field, 1, 0); }
 -  bool register_field_in_read_map(uchar *arg);
 -  bool register_field_in_bitmap(uchar *arg);
 +  bool register_field_in_read_map(void *arg);
 +  bool register_field_in_bitmap(void *arg);
    bool set_entry(THD *thd, bool create_if_not_exists);
    void cleanup();
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_set_user_var>(thd, mem_root, this); }
  };
  
  
@@@ -1934,7 -2043,9 +2064,9 @@@ public
    bool eq(const Item *item, bool binary_cmp) const;
  
    void cleanup();
 -  bool check_vcol_func_processor(uchar *int_arg) { return TRUE;}
 +  bool check_vcol_func_processor(void *arg);
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_get_system_var>(thd, mem_root, this); }
  };
  
  
@@@ -1980,10 -2091,14 +2112,13 @@@ public
  
    bool fix_index();
    void init_search(THD *thd, bool no_order);
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -    /* TODO: consider adding in support for the MATCH-based virtual columns */
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return mark_unsupported_function("match ... against()", arg, VCOL_IMPOSSIBLE);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_match>(thd, mem_root, this); }
+   Item *build_clone(THD *thd, MEM_ROOT *mem_root) { return 0; }
  private:
    /**
       Check whether storage engine for given table, 
@@@ -2037,10 -2155,12 +2174,12 @@@ public
    longlong val_int();
    const char *func_name() const { return "is_free_lock"; }
    void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_is_free_lock>(thd, mem_root, this); }
  };
  
  class Item_func_is_used_lock :public Item_int_func
@@@ -2051,10 -2171,12 +2190,12 @@@ public
    longlong val_int();
    const char *func_name() const { return "is_used_lock"; }
    void fix_length_and_dec() { decimals=0; max_length=10; maybe_null=1;}
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_is_used_lock>(thd, mem_root, this); }
  };
  
  /* For type casts */
@@@ -2101,10 -2223,13 +2242,12 @@@ public
    longlong val_int();
    const char *func_name() const { return "row_count"; }
    void fix_length_and_dec() { decimals= 0; maybe_null=0; }
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_row_count>(thd, mem_root, this); }
  };
  
  
@@@ -2242,10 -2379,12 +2394,12 @@@ public
    longlong val_int();
    const char *func_name() const { return "found_rows"; }
    void fix_length_and_dec() { decimals= 0; maybe_null=0; }
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_found_rows>(thd, mem_root, this); }
  };
  
  
@@@ -2259,11 -2398,12 +2413,13 @@@ public
    longlong val_int();
    void fix_length_and_dec()
    { max_length= 21; unsigned_flag=1; }
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  table_map used_tables() const { return RAND_TABLE_BIT; }
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_uuid_short>(thd, mem_root, this); }
  };
  
  
diff --cc sql/item_geofunc.h
index 58e1d0a,9a2a49f..f96e570
--- a/sql/item_geofunc.h
+++ b/sql/item_geofunc.h
@@@ -299,7 -325,7 +325,8 @@@ public
      return add_key_fields_optimize_op(join, key_fields, and_level,
                                        usable_tables, sargables, false);
    }
 +  bool need_parentheses_in_default() { return false; }
+   Item *build_clone(THD *thd, MEM_ROOT *mem_root) { return 0; }
  };
  
  
@@@ -340,7 -370,8 +371,9 @@@ public
    { }
    longlong val_int();
    const char *func_name() const { return "st_relate"; }
 +  bool need_parentheses_in_default() { return false; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_spatial_relate>(thd, mem_root, this); }
  };
  
  
@@@ -431,7 -466,8 +468,9 @@@ public
    longlong val_int();
    const char *func_name() const { return "st_isempty"; }
    void fix_length_and_dec() { maybe_null= 1; }
 +  bool need_parentheses_in_default() { return false; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_isempty>(thd, mem_root, this); }
  };
  
  class Item_func_issimple: public Item_int_func
@@@ -616,10 -680,8 +683,12 @@@ class Item_func_gis_debug: public Item_
      { null_value= false; }
      const char *func_name() const  { return "st_gis_debug"; }
      longlong val_int();
 +    bool check_vcol_func_processor(void *arg)
 +    {
 +      return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
 +    }
+     Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+     { return get_item_copy<Item_func_gis_debug>(thd, mem_root, this); }
  };
  #endif
  
diff --cc sql/item_row.h
index eb26860,de8a4c9..bbfebb5
--- a/sql/item_row.h
+++ b/sql/item_row.h
@@@ -119,7 -119,10 +119,10 @@@ public
    bool check_cols(uint c);
    bool null_inside() { return with_null; };
    void bring_value();
 -  bool check_vcol_func_processor(uchar *int_arg) {return FALSE; } 
 +  bool check_vcol_func_processor(void *arg) {return FALSE; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_row>(thd, mem_root, this); }
+   Item *build_clone(THD *thd, MEM_ROOT *mem_root);
  };
  
  #endif /* ITEM_ROW_INCLUDED */
diff --cc sql/item_strfunc.h
index fd63c57,b20fb4e..25b63eb
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@@ -517,10 -572,12 +572,12 @@@ public
    String *val_str(String *);
    void fix_length_and_dec() { maybe_null=1; max_length = 13; }
    const char *func_name() const { return "encrypt"; }
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return FALSE;
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_encrypt>(thd, mem_root, this); }
  };
  
  #include "sql_crypt.h"
@@@ -663,12 -722,8 +728,15 @@@ public
      DBUG_ASSERT(fixed == 1);
      return (null_value ? 0 : &str_value);
    }
 +  bool check_vcol_func_processor(void *arg)
 +  {
++
 +    context= 0;
 +    return mark_unsupported_function(fully_qualified_func_name(), arg,
 +                                     VCOL_SESSION_FUNC);
 +  }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_current_role>(thd, mem_root, this); }
  };
  
  
@@@ -773,10 -842,8 +855,13 @@@ public
    String *val_str(String *);
    void fix_length_and_dec();
    const char *func_name() const { return "binlog_gtid_pos"; }
 +  bool check_vcol_func_processor(void *arg)
 +  {
++
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
 +  }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_binlog_gtid_pos>(thd, mem_root, this); }
  };
  
  
@@@ -916,7 -997,8 +1015,9 @@@ public
    }
    virtual void print(String *str, enum_query_type query_type);
    const char *func_name() const { return "cast_as_binary"; }
 +  bool need_parentheses_in_default() { return true; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_binary>(thd, mem_root, this); }
  };
  
  
@@@ -933,10 -1015,12 +1034,12 @@@ public
      maybe_null=1;
      max_length=MAX_BLOB_WIDTH;
    }
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_load_file>(thd, mem_root, this); }
  };
  
  
@@@ -1069,7 -1159,8 +1178,9 @@@ public
      /* this function is transparent for view updating */
      return args[0]->field_for_view_update();
    }
 +  bool need_parentheses_in_default() { return true; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_set_collation>(thd, mem_root, this); }
  };
  
  
@@@ -1201,10 -1306,12 +1326,12 @@@ public
    }
    const char *func_name() const{ return "uuid"; }
    String *val_str(String *);
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor(func_name());
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC);
    }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_uuid>(thd, mem_root, this); }
  };
  
  
diff --cc sql/item_sum.h
index 4cb5529,15cfd1f..9fd6f78
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@@ -1226,6 -1254,12 +1250,8 @@@ public
    bool is_null() { update_null_value(); return null_value; }
    enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
    enum Item_result result_type () const { return REAL_RESULT; }
 -  bool check_vcol_func_processor(uchar *int_arg)
 -  {
 -    return trace_unsupported_by_check_vcol_func_processor("var_field");
 -  }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_variance_field>(thd, mem_root, this); }
  };
  
  
@@@ -1596,8 -1640,10 +1632,10 @@@ public
    Item *copy_or_same(THD* thd);
    void no_rows_in_result() {}
    virtual void print(String *str, enum_query_type query_type);
 -  virtual bool change_context_processor(uchar *cntx)
 +  virtual bool change_context_processor(void *cntx)
      { context= (Name_resolution_context *)cntx; return FALSE; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_group_concat>(thd, mem_root, this); }
  };
  
  #endif /* ITEM_SUM_INCLUDED */
diff --cc sql/item_timefunc.h
index 84f610b,0edfc4f..d9de9b9
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@@ -194,10 -207,8 +206,13 @@@ public
    {
      return !has_date_args();
    }
 +  bool check_vcol_func_processor(void *arg)
 +  {
++
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC);
 +  }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_monthname>(thd, mem_root, this); }
  };
  
  
@@@ -624,7 -660,9 +661,9 @@@ class Item_func_curtime_local :public I
  public:
    Item_func_curtime_local(THD *thd, uint dec): Item_func_curtime(thd, dec) {}
    const char *func_name() const { return "curtime"; }
 -  virtual void store_now_in_TIME(MYSQL_TIME *now_time);
 +  virtual void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time);
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_curtime_local>(thd, mem_root, this); }
  };
  
  
@@@ -633,7 -671,9 +672,9 @@@ class Item_func_curtime_utc :public Ite
  public:
    Item_func_curtime_utc(THD *thd, uint dec): Item_func_curtime(thd, dec) {}
    const char *func_name() const { return "utc_time"; }
 -  virtual void store_now_in_TIME(MYSQL_TIME *now_time);
 +  virtual void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time);
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_curtime_utc>(thd, mem_root, this); }
  };
  
  
@@@ -660,7 -699,9 +701,9 @@@ class Item_func_curdate_local :public I
  public:
    Item_func_curdate_local(THD *thd): Item_func_curdate(thd) {}
    const char *func_name() const { return "curdate"; }
 -  void store_now_in_TIME(MYSQL_TIME *now_time);
 +  void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time);
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_curdate_local>(thd, mem_root, this); }
  };
  
  
@@@ -669,7 -710,9 +712,9 @@@ class Item_func_curdate_utc :public Ite
  public:
    Item_func_curdate_utc(THD *thd): Item_func_curdate(thd) {}
    const char *func_name() const { return "utc_date"; }
 -  void store_now_in_TIME(MYSQL_TIME *now_time);
 +  void store_now_in_TIME(THD* thd, MYSQL_TIME *now_time);
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_curdate_utc>(thd, mem_root, this); }
  };
  
  
@@@ -701,8 -745,10 +746,10 @@@ class Item_func_now_local :public Item_
  public:
    Item_func_now_local(THD *thd, uint dec): Item_func_now(thd, dec) {}
    const char *func_name() const { return "now"; }
 -  virtual void store_now_in_TIME(MYSQL_TIME *now_time);
 +  virtual void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time);
    virtual enum Functype functype() const { return NOW_FUNC; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_now_local>(thd, mem_root, this); }
  };
  
  
@@@ -711,14 -757,9 +758,15 @@@ class Item_func_now_utc :public Item_fu
  public:
    Item_func_now_utc(THD *thd, uint dec): Item_func_now(thd, dec) {}
    const char *func_name() const { return "utc_timestamp"; }
 -  virtual void store_now_in_TIME(MYSQL_TIME *now_time);
 +  virtual void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time);
 +  virtual enum Functype functype() const { return NOW_UTC_FUNC; }
 +  virtual bool check_vcol_func_processor(void *arg)
 +  {
 +    return mark_unsupported_function(func_name(), "()", arg,
 +                                     VCOL_TIME_FUNC | VCOL_NON_DETERMINISTIC);
 +  }
- 
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_now_utc>(thd, mem_root, this); }
  };
  
  
@@@ -732,15 -773,16 +780,17 @@@ public
    Item_func_sysdate_local(THD *thd, uint dec): Item_func_now(thd, dec) {}
    bool const_item() const { return 0; }
    const char *func_name() const { return "sysdate"; }
 -  void store_now_in_TIME(MYSQL_TIME *now_time);
 +  void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time);
    bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
 -  void update_used_tables()
 +  table_map used_tables() const { return RAND_TABLE_BIT; }
 +  bool check_vcol_func_processor(void *arg)
    {
 -    Item_func_now::update_used_tables();
 -    maybe_null= 0;
 -    used_tables_cache|= RAND_TABLE_BIT;
 +    return mark_unsupported_function(func_name(), "()", arg,
 +                                     VCOL_TIME_FUNC | VCOL_NON_DETERMINISTIC);
    }
 +  virtual enum Functype functype() const { return SYSDATE_FUNC; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_sysdate_local>(thd, mem_root, this); }
  };
  
  
@@@ -774,10 -818,8 +826,12 @@@ public
    void fix_length_and_dec();
    uint format_length(const String *format);
    bool eq(const Item *item, bool binary_cmp) const;
 +  bool check_vcol_func_processor(void *arg)
 +  {
 +    return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC);
 +  }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_func_date_format>(thd, mem_root, this); }
  };
  
  
@@@ -854,7 -902,8 +914,9 @@@ public
    bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
    bool eq(const Item *item, bool binary_cmp) const;
    void print(String *str, enum_query_type query_type);
 +  bool need_parentheses_in_default() { return true; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_date_add_interval>(thd, mem_root, this); }
  };
  
  
@@@ -932,7 -983,8 +996,9 @@@ public
    String *val_str(String *a);
    void fix_length_and_dec();
    void print(String *str, enum_query_type query_type);
 +  bool need_parentheses_in_default() { return true; }
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_char_typecast>(thd, mem_root, this); }
  };
  
  
diff --cc sql/item_windowfunc.h
index 9d2fa13,90ecd27..163cc85
--- a/sql/item_windowfunc.h
+++ b/sql/item_windowfunc.h
@@@ -117,9 -117,10 +117,10 @@@ public
    }
    const char*func_name() const
    {
 -    return "row_number";
 +    return "row_number(";
    }
-   
+   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+   { return get_item_copy<Item_sum_row_number>(thd, mem_root, this); }
  };
  
  
diff --cc sql/procedure.h
index be63167,adbff84..b9d5066
--- a/sql/procedure.h
+++ b/sql/procedure.h
@@@ -53,11 -53,11 +53,12 @@@ public
      init_make_field(tmp_field,field_type());
    }
    unsigned int size_of() { return sizeof(*this);}
 -  bool check_vcol_func_processor(uchar *int_arg) 
 +  bool check_vcol_func_processor(void *arg)
    {
 -    return trace_unsupported_by_check_vcol_func_processor("proc"); 
 +    DBUG_ASSERT(0); // impossible
 +    return mark_unsupported_function("proc", arg, VCOL_IMPOSSIBLE);
    }
+   Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
  };
  
  class Item_proc_real :public Item_proc
diff --cc sql/sql_lex.h
index 128b574,77c9b9c..97d1f00
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@@ -922,8 -925,8 +937,9 @@@ public
  
    /* namp of nesting SELECT visibility (for aggregate functions check) */
    nesting_map name_visibility_map;
- 
+   
 +  table_map with_dep;
+   List<Grouping_tmp_field> grouping_tmp_fields;
  
    void init_query();
    void init_select();
@@@ -1108,9 -1114,12 +1124,14 @@@
      return master_unit()->with_element;
    }
    With_element *find_table_def_in_with_clauses(TABLE_LIST *table);
 +  bool check_unrestricted_recursive(bool only_standards_compliant); 
 +  bool check_subqueries_with_recursive_references();
+   void collect_grouping_fields(THD *thd); 
+   void check_cond_extraction_for_grouping_fields(Item *cond,
+                                                  Item_processor processor);
+   Item *build_cond_for_grouping_fields(THD *thd, Item *cond,
+ 				       bool no_to_clones);
 -
 +  
    List<Window_spec> window_specs;
    void prepare_add_window_spec(THD *thd);
    bool add_window_def(THD *thd, LEX_STRING *win_name, LEX_STRING *win_ref,
diff --cc sql/sql_priv.h
index 40349d3,0d19ad1..4bf9304
--- a/sql/sql_priv.h
+++ b/sql/sql_priv.h
@@@ -225,7 -224,7 +225,8 @@@
  #define OPTIMIZER_SWITCH_TABLE_ELIMINATION         (1ULL << 26)
  #define OPTIMIZER_SWITCH_EXTENDED_KEYS             (1ULL << 27)
  #define OPTIMIZER_SWITCH_EXISTS_TO_IN              (1ULL << 28)
 -#define OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED (1ULL << 29)
 +#define OPTIMIZER_SWITCH_ORDERBY_EQ_PROP           (1ULL << 29)
++#define OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED (1ULL << 30)
  
  #define OPTIMIZER_SWITCH_DEFAULT   (OPTIMIZER_SWITCH_INDEX_MERGE | \
                                      OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
diff --cc sql/sys_vars.cc
index ddceb67,881c671..b0a4b3f
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@@ -2389,9 -2382,8 +2389,10 @@@ export const char *optimizer_switch_nam
    "table_elimination",
    "extended_keys",
    "exists_to_in",
 +  "orderby_uses_equalities",
+   "condition_pushdown_for_derived",
 -  "default", NullS
 +  "default", 
 +  NullS
  };
  static bool fix_optimizer_switch(sys_var *self, THD *thd,
                                   enum_var_type type)



More information about the commits mailing list