diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h
index 50ec051d111fd2243c7569517799737903bcd563..5094f65cb598cc5980eb570f02e131fd6b003db3 100644
--- a/include/mysql/plugin.h
+++ b/include/mysql/plugin.h
@@ -187,7 +187,7 @@ typedef int (*mysql_var_check_func)(MYSQL_THD thd,
 */
 typedef void (*mysql_var_update_func)(MYSQL_THD thd,
                                       struct st_mysql_sys_var *var,
-                                      void *var_ptr, void *save);
+                                      void *var_ptr, const void *save);
 
 
 /* the following declarations are for internal use only */
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 74c99b5773d72dc70f0c6d95baacb37dfd5b3849..ccb1a3a8af01025c3d9eeb58865e70cce31a9101 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -2088,35 +2088,35 @@ static int check_func_set(THD *thd, struct st_mysql_sys_var *var,
 
 
 static void update_func_bool(THD *thd, struct st_mysql_sys_var *var,
-                             void *tgt, void *save)
+                             void *tgt, const void *save)
 {
   *(my_bool *) tgt= *(int *) save ? 1 : 0;
 }
 
 
 static void update_func_int(THD *thd, struct st_mysql_sys_var *var,
-                             void *tgt, void *save)
+                             void *tgt, const void *save)
 {
   *(int *)tgt= *(int *) save;
 }
 
 
 static void update_func_long(THD *thd, struct st_mysql_sys_var *var,
-                             void *tgt, void *save)
+                             void *tgt, const void *save)
 {
   *(long *)tgt= *(long *) save;
 }
 
 
 static void update_func_longlong(THD *thd, struct st_mysql_sys_var *var,
-                             void *tgt, void *save)
+                             void *tgt, const void *save)
 {
   *(longlong *)tgt= *(ulonglong *) save;
 }
 
 
 static void update_func_str(THD *thd, struct st_mysql_sys_var *var,
-                             void *tgt, void *save)
+                             void *tgt, const void *save)
 {
   char *old= *(char **) tgt;
   *(char **)tgt= *(char **) save;
@@ -2673,7 +2673,8 @@ bool sys_var_pluginvar::check(THD *thd, set_var *var)
 
 void sys_var_pluginvar::set_default(THD *thd, enum_var_type type)
 {
-  void *tgt, *src;
+  const void *src;
+  void *tgt;
 
   DBUG_ASSERT(is_readonly() || plugin_var->update);
 
@@ -2686,9 +2687,34 @@ void sys_var_pluginvar::set_default(THD *thd, enum_var_type type)
 
   if (plugin_var->flags & PLUGIN_VAR_THDLOCAL)
   {
-    src= ((int*) (plugin_var + 1) + 1);
     if (type != OPT_GLOBAL)
       src= real_value_ptr(thd, OPT_GLOBAL);
+    else
+    switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
+	case PLUGIN_VAR_INT:
+	  src= &((thdvar_uint_t*) plugin_var)->def_val;
+	  break;
+	case PLUGIN_VAR_LONG:
+	  src= &((thdvar_ulong_t*) plugin_var)->def_val;
+	  break;
+	case PLUGIN_VAR_LONGLONG:
+	  src= &((thdvar_ulonglong_t*) plugin_var)->def_val;
+	  break;
+	case PLUGIN_VAR_ENUM:
+	  src= &((thdvar_enum_t*) plugin_var)->def_val;
+	  break;
+	case PLUGIN_VAR_SET:
+	  src= &((thdvar_set_t*) plugin_var)->def_val;
+	  break;
+	case PLUGIN_VAR_BOOL:
+	  src= &((thdvar_bool_t*) plugin_var)->def_val;
+	  break;
+	case PLUGIN_VAR_STR:
+	  src= &((thdvar_str_t*) plugin_var)->def_val;
+	  break;
+	default:
+	  DBUG_ASSERT(0);
+	}
   }
 
   /* thd must equal current_thd if PLUGIN_VAR_THDLOCAL flag is set */
@@ -2776,25 +2802,25 @@ static void plugin_opt_set_limits(struct my_option *options,
   case PLUGIN_VAR_ENUM:
     options->var_type= GET_ENUM;
     options->typelib= ((sysvar_enum_t*) opt)->typelib;
-    options->def_value= *(ulong*) ((int*) (opt + 1) + 1);
+    options->def_value= ((sysvar_enum_t*) opt)->def_val;
     options->min_value= options->block_size= 0;
     options->max_value= options->typelib->count - 1;
     break;
   case PLUGIN_VAR_SET:
     options->var_type= GET_SET;
     options->typelib= ((sysvar_set_t*) opt)->typelib;
-    options->def_value= *(ulonglong*) ((int*) (opt + 1) + 1);
+    options->def_value= ((sysvar_set_t*) opt)->def_val;
     options->min_value= options->block_size= 0;
     options->max_value= (ULL(1) << options->typelib->count) - 1;
     break;
   case PLUGIN_VAR_BOOL:
     options->var_type= GET_BOOL;
-    options->def_value= *(my_bool*) ((void**)(opt + 1) + 1);
+    options->def_value= ((sysvar_bool_t*) opt)->def_val;
     break;
   case PLUGIN_VAR_STR:
     options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ?
                         GET_STR_ALLOC : GET_STR);
-    options->def_value= (ulonglong)(intptr) *((char**) ((void**) (opt + 1) + 1));
+    options->def_value= (intptr) ((sysvar_str_t*) opt)->def_val;
     break;
   /* threadlocal variables */
   case PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL:
@@ -2818,25 +2844,25 @@ static void plugin_opt_set_limits(struct my_option *options,
   case PLUGIN_VAR_ENUM | PLUGIN_VAR_THDLOCAL:
     options->var_type= GET_ENUM;
     options->typelib= ((thdvar_enum_t*) opt)->typelib;
-    options->def_value= *(ulong*) ((int*) (opt + 1) + 1);
+    options->def_value= ((thdvar_enum_t*) opt)->def_val;
     options->min_value= options->block_size= 0;
     options->max_value= options->typelib->count - 1;
     break;
   case PLUGIN_VAR_SET | PLUGIN_VAR_THDLOCAL:
     options->var_type= GET_SET;
     options->typelib= ((thdvar_set_t*) opt)->typelib;
-    options->def_value= *(ulonglong*) ((int*) (opt + 1) + 1);
+    options->def_value= ((thdvar_set_t*) opt)->def_val;
     options->min_value= options->block_size= 0;
     options->max_value= (ULL(1) << options->typelib->count) - 1;
     break;
   case PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL:
     options->var_type= GET_BOOL;
-    options->def_value= *(my_bool*) ((int*) (opt + 1) + 1);
+    options->def_value= ((thdvar_bool_t*) opt)->def_val;
     break;
   case PLUGIN_VAR_STR | PLUGIN_VAR_THDLOCAL:
     options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ?
                         GET_STR_ALLOC : GET_STR);
-    options->def_value= (intptr) *((char**) ((void**) (opt + 1) + 1));
+    options->def_value= (intptr) ((thdvar_str_t*) opt)->def_val;
     break;
   default:
     DBUG_ASSERT(0);