~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/sql_plugin.cc

  • Committer: Mark Atwood
  • Date: 2008-07-12 07:25:25 UTC
  • mto: This revision was merged to the branch mainline in revision 139.
  • Revision ID: me@mark.atwood.name-20080712072525-s1dq9mtwo5td7af7
more hackery to get plugin UDFs working

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
   along with this program; if not, write to the Free Software
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
 
#include <drizzled/server_includes.h>
17
 
#include <mysys/my_getopt.h>
18
 
#include <authentication.h>
19
 
#include <logging.h>
20
 
#include <drizzled/drizzled_error_messages.h>
 
16
#include "mysql_priv.h"
 
17
#include <my_pthread.h>
 
18
#include <my_getopt.h>
21
19
#define REPORT_TO_LOG  1
22
20
#define REPORT_TO_USER 2
23
21
 
33
31
  When you ad a new plugin type, add both a string and make sure that the
34
32
  init and deinit array are correctly updated.
35
33
*/
36
 
const LEX_STRING plugin_type_names[DRIZZLE_MAX_PLUGIN_TYPE_NUM]=
 
34
const LEX_STRING plugin_type_names[MYSQL_MAX_PLUGIN_TYPE_NUM]=
37
35
{
 
36
  { C_STRING_WITH_LEN("UDF") },
 
37
  { C_STRING_WITH_LEN("STORAGE ENGINE") },
 
38
  { C_STRING_WITH_LEN("FTPARSER") },
38
39
  { C_STRING_WITH_LEN("DAEMON") },
39
 
  { C_STRING_WITH_LEN("STORAGE ENGINE") },
40
40
  { C_STRING_WITH_LEN("INFORMATION SCHEMA") },
41
 
  { C_STRING_WITH_LEN("UDF") },
42
 
  { C_STRING_WITH_LEN("UDA") },
43
 
  { C_STRING_WITH_LEN("AUDIT") },
44
 
  { C_STRING_WITH_LEN("LOGGER") },
45
 
  { C_STRING_WITH_LEN("AUTH") }
 
41
  { C_STRING_WITH_LEN("AUDIT") }
46
42
};
47
43
 
48
44
extern int initialize_schema_table(st_plugin_int *plugin);
56
52
  plugin_type_deinitialize should equal to the number of plugins
57
53
  defined.
58
54
*/
59
 
plugin_type_init plugin_type_initialize[DRIZZLE_MAX_PLUGIN_TYPE_NUM]=
60
 
{
61
 
  0,  /* Daemon */
62
 
  ha_initialize_handlerton,  /* Storage Engine */
63
 
  initialize_schema_table,  /* Information Schema */
64
 
  initialize_udf,  /* UDF */
65
 
  0,  /* UDA */
66
 
  0,  /* Audit */
67
 
  logging_initializer,  /* Logger */
68
 
  authentication_initializer  /* Auth */
69
 
};
70
 
 
71
 
plugin_type_init plugin_type_deinitialize[DRIZZLE_MAX_PLUGIN_TYPE_NUM]=
72
 
{
73
 
  0,  /* Daemon */
74
 
  ha_finalize_handlerton,  /* Storage Engine */
75
 
  finalize_schema_table,  /* Information Schema */
76
 
  finalize_udf,  /* UDF */
77
 
  0,  /* UDA */
78
 
  0,  /* Audit */
79
 
  logging_finalizer,  /* Logger */
80
 
  authentication_finalizer  /* Auth */
81
 
};
82
 
 
 
55
plugin_type_init plugin_type_initialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
 
56
{
 
57
  initialize_udf,ha_initialize_handlerton,0,0,initialize_schema_table,
 
58
  0
 
59
};
 
60
 
 
61
plugin_type_init plugin_type_deinitialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
 
62
{
 
63
  finalize_udf,ha_finalize_handlerton,0,0,finalize_schema_table,
 
64
  0
 
65
};
 
66
 
 
67
static const char *plugin_interface_version_sym=
 
68
                   "_mysql_plugin_interface_version_";
 
69
static const char *sizeof_st_plugin_sym=
 
70
                   "_mysql_sizeof_struct_st_plugin_";
83
71
static const char *plugin_declarations_sym= "_mysql_plugin_declarations_";
 
72
static int min_plugin_interface_version= MYSQL_PLUGIN_INTERFACE_VERSION & ~0xFF;
84
73
 
85
74
/* Note that 'int version' must be the first field of every plugin
86
75
   sub-structure (plugin->info).
87
76
*/
 
77
static int min_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
 
78
{
 
79
  MYSQL_UDF_INTERFACE_VERSION,
 
80
  MYSQL_HANDLERTON_INTERFACE_VERSION,
 
81
  MYSQL_FTPARSER_INTERFACE_VERSION,
 
82
  MYSQL_DAEMON_INTERFACE_VERSION,
 
83
  MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
 
84
  MYSQL_AUDIT_INTERFACE_VERSION
 
85
};
 
86
static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
 
87
{
 
88
  MYSQL_UDF_INTERFACE_VERSION,
 
89
  MYSQL_HANDLERTON_INTERFACE_VERSION,
 
90
  MYSQL_FTPARSER_INTERFACE_VERSION,
 
91
  MYSQL_DAEMON_INTERFACE_VERSION,
 
92
  MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
 
93
  MYSQL_AUDIT_INTERFACE_VERSION
 
94
};
88
95
 
89
96
static bool initialized= 0;
90
97
 
91
98
static DYNAMIC_ARRAY plugin_dl_array;
92
99
static DYNAMIC_ARRAY plugin_array;
93
 
static HASH plugin_hash[DRIZZLE_MAX_PLUGIN_TYPE_NUM];
 
100
static HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM];
94
101
static bool reap_needed= false;
95
102
static int plugin_array_version=0;
96
103
 
99
106
  the following variables/structures
100
107
*/
101
108
static MEM_ROOT plugin_mem_root;
102
 
static uint32_t global_variables_dynamic_size= 0;
 
109
static uint global_variables_dynamic_size= 0;
103
110
static HASH bookmark_hash;
104
111
 
105
112
 
126
133
*/
127
134
struct st_bookmark
128
135
{
129
 
  uint32_t name_len;
 
136
  uint name_len;
130
137
  int offset;
131
 
  uint32_t version;
 
138
  uint version;
132
139
  char key[1];
133
140
};
134
141
 
138
145
*/
139
146
struct st_mysql_sys_var
140
147
{
141
 
  DRIZZLE_PLUGIN_VAR_HEADER;
 
148
  MYSQL_PLUGIN_VAR_HEADER;
142
149
};
143
150
 
144
151
 
153
160
 
154
161
  static void *operator new(size_t size, MEM_ROOT *mem_root)
155
162
  { return (void*) alloc_root(mem_root, (uint) size); }
156
 
  static void operator delete(void *ptr_arg __attribute__((unused)),
157
 
                              size_t size __attribute__((unused)))
 
163
  static void operator delete(void *ptr_arg __attribute__((__unused__)),
 
164
                              size_t size __attribute__((__unused__)))
158
165
  { TRASH(ptr_arg, size); }
159
166
 
160
167
  sys_var_pluginvar(const char *name_arg,
166
173
  { return !(plugin_var->flags & PLUGIN_VAR_THDLOCAL) && type != OPT_GLOBAL; }
167
174
  bool check_update_type(Item_result type);
168
175
  SHOW_TYPE show_type();
169
 
  unsigned char* real_value_ptr(THD *thd, enum_var_type type);
 
176
  uchar* real_value_ptr(THD *thd, enum_var_type type);
170
177
  TYPELIB* plugin_var_typelib(void);
171
 
  unsigned char* value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
 
178
  uchar* value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
172
179
  bool check(THD *thd, set_var *var);
173
 
  bool check_default(enum_var_type type __attribute__((unused)))
 
180
  bool check_default(enum_var_type type __attribute__((__unused__)))
174
181
    { return is_readonly(); }
175
182
  void set_default(THD *thd,
176
 
                   enum_var_type type __attribute__((unused)));
 
183
                   enum_var_type type __attribute__((__unused__)));
177
184
  bool update(THD *thd, set_var *var);
178
185
};
179
186
 
182
189
static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
183
190
                             const char *list);
184
191
static int test_plugin_options(MEM_ROOT *, struct st_plugin_int *,
185
 
                               int *, char **);
 
192
                               int *, char **, my_bool);
186
193
static bool register_builtin(struct st_mysql_plugin *, struct st_plugin_int *,
187
194
                             struct st_plugin_int **);
188
195
static void unlock_variables(THD *thd, struct system_variables *vars);
199
206
 
200
207
 
201
208
/* declared in set_var.cc */
202
 
extern sys_var *intern_find_sys_var(const char *str, uint32_t length, bool no_error);
 
209
extern sys_var *intern_find_sys_var(const char *str, uint length, bool no_error);
203
210
extern bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
204
 
                                 const char *name, int64_t val);
 
211
                                 const char *name, longlong val);
205
212
 
206
213
/****************************************************************************
207
214
  Value type thunks, allows the C world to play in the C++ world
211
218
{
212
219
  switch (((st_item_value_holder*)value)->item->result_type()) {
213
220
  case INT_RESULT:
214
 
    return DRIZZLE_VALUE_TYPE_INT;
 
221
    return MYSQL_VALUE_TYPE_INT;
215
222
  case REAL_RESULT:
216
 
    return DRIZZLE_VALUE_TYPE_REAL;
 
223
    return MYSQL_VALUE_TYPE_REAL;
217
224
  default:
218
 
    return DRIZZLE_VALUE_TYPE_STRING;
 
225
    return MYSQL_VALUE_TYPE_STRING;
219
226
  }
220
227
}
221
228
 
263
270
 
264
271
static struct st_plugin_dl *plugin_dl_find(const LEX_STRING *dl)
265
272
{
266
 
  uint32_t i;
 
273
  uint i;
267
274
  struct st_plugin_dl *tmp;
268
275
  for (i= 0; i < plugin_dl_array.elements; i++)
269
276
  {
270
277
    tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
271
278
    if (tmp->ref_count &&
272
279
        ! my_strnncoll(files_charset_info,
273
 
                       (const unsigned char *)dl->str, dl->length,
274
 
                       (const unsigned char *)tmp->dl.str, tmp->dl.length))
 
280
                       (const uchar *)dl->str, dl->length,
 
281
                       (const uchar *)tmp->dl.str, tmp->dl.length))
275
282
      return(tmp);
276
283
  }
277
284
  return(0);
279
286
 
280
287
static st_plugin_dl *plugin_dl_insert_or_reuse(struct st_plugin_dl *plugin_dl)
281
288
{
282
 
  uint32_t i;
 
289
  uint i;
283
290
  struct st_plugin_dl *tmp;
284
291
  for (i= 0; i < plugin_dl_array.elements; i++)
285
292
  {
290
297
      return(tmp);
291
298
    }
292
299
  }
293
 
  if (insert_dynamic(&plugin_dl_array, (unsigned char*)&plugin_dl))
 
300
  if (insert_dynamic(&plugin_dl_array, (uchar*)&plugin_dl))
294
301
    return(0);
295
302
  tmp= *dynamic_element(&plugin_dl_array, plugin_dl_array.elements - 1,
296
303
                        struct st_plugin_dl **)=
297
 
      (struct st_plugin_dl *) memdup_root(&plugin_mem_root, (unsigned char*)plugin_dl,
 
304
      (struct st_plugin_dl *) memdup_root(&plugin_mem_root, (uchar*)plugin_dl,
298
305
                                           sizeof(struct st_plugin_dl));
299
306
  return(tmp);
300
307
}
303
310
{
304
311
  if (p->handle)
305
312
    dlclose(p->handle);
306
 
  free(p->dl.str);
 
313
  my_free(p->dl.str, MYF(MY_ALLOW_ZERO_PTR));
 
314
  if (p->version != MYSQL_PLUGIN_INTERFACE_VERSION)
 
315
    my_free((uchar*)p->plugins, MYF(MY_ALLOW_ZERO_PTR));
307
316
}
308
317
 
309
318
 
310
319
static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
311
320
{
 
321
#ifdef HAVE_DLOPEN
312
322
  char dlpath[FN_REFLEN];
313
 
  uint32_t plugin_dir_len, dummy_errors, dlpathlen;
 
323
  uint plugin_dir_len, dummy_errors, dlpathlen;
314
324
  struct st_plugin_dl *tmp, plugin_dl;
315
325
  void *sym;
316
326
  plugin_dir_len= strlen(opt_plugin_dir);
319
329
    This is done to ensure that only approved libraries from the
320
330
    plugin directory are used (to make this even remotely secure).
321
331
  */
322
 
  if (strchr(dl->str, FN_LIBCHAR) ||
 
332
  if (my_strchr(files_charset_info, dl->str, dl->str + dl->length, FN_LIBCHAR) ||
323
333
      check_string_char_length((LEX_STRING *) dl, "", NAME_CHAR_LEN,
324
334
                               system_charset_info, 1) ||
325
335
      plugin_dir_len + dl->length + 1 >= FN_REFLEN)
336
346
    tmp->ref_count++;
337
347
    return(tmp);
338
348
  }
339
 
  memset(&plugin_dl, 0, sizeof(plugin_dl));
 
349
  bzero(&plugin_dl, sizeof(plugin_dl));
340
350
  /* Compile dll path */
341
351
  dlpathlen=
342
 
    strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", dl->str, NULL) -
 
352
    strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", dl->str, NullS) -
343
353
    dlpath;
344
354
  plugin_dl.ref_count= 1;
345
355
  /* Open new dll handle */
346
 
  if (!(plugin_dl.handle= dlopen(dlpath, RTLD_LAZY|RTLD_GLOBAL)))
 
356
  if (!(plugin_dl.handle= dlopen(dlpath, RTLD_NOW)))
347
357
  {
348
358
    const char *errmsg=dlerror();
349
359
    if (!strncmp(dlpath, errmsg, dlpathlen))
358
368
      sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dlpath, errno, errmsg);
359
369
    return(0);
360
370
  }
361
 
 
 
371
  /* Determine interface version */
 
372
  if (!(sym= dlsym(plugin_dl.handle, plugin_interface_version_sym)))
 
373
  {
 
374
    free_plugin_mem(&plugin_dl);
 
375
    if (report & REPORT_TO_USER)
 
376
      my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_interface_version_sym);
 
377
    if (report & REPORT_TO_LOG)
 
378
      sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), plugin_interface_version_sym);
 
379
    return(0);
 
380
  }
 
381
  plugin_dl.version= *(int *)sym;
 
382
  /* Versioning */
 
383
  if (plugin_dl.version < min_plugin_interface_version ||
 
384
      (plugin_dl.version >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8))
 
385
  {
 
386
    free_plugin_mem(&plugin_dl);
 
387
    if (report & REPORT_TO_USER)
 
388
      my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, 0,
 
389
               "plugin interface version mismatch");
 
390
    if (report & REPORT_TO_LOG)
 
391
      sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dlpath, 0,
 
392
                      "plugin interface version mismatch");
 
393
    return(0);
 
394
  }
362
395
  /* Find plugin declarations */
363
396
  if (!(sym= dlsym(plugin_dl.handle, plugin_declarations_sym)))
364
397
  {
370
403
    return(0);
371
404
  }
372
405
 
 
406
  if (plugin_dl.version != MYSQL_PLUGIN_INTERFACE_VERSION)
 
407
  {
 
408
    int i;
 
409
    uint sizeof_st_plugin;
 
410
    struct st_mysql_plugin *old, *cur;
 
411
    char *ptr= (char *)sym;
 
412
 
 
413
    if ((sym= dlsym(plugin_dl.handle, sizeof_st_plugin_sym)))
 
414
      sizeof_st_plugin= *(int *)sym;
 
415
    else
 
416
    {
 
417
#ifdef ERROR_ON_NO_SIZEOF_PLUGIN_SYMBOL
 
418
      free_plugin_mem(&plugin_dl);
 
419
      if (report & REPORT_TO_USER)
 
420
        my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), sizeof_st_plugin_sym);
 
421
      if (report & REPORT_TO_LOG)
 
422
        sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), sizeof_st_plugin_sym);
 
423
      return(0);
 
424
#else
 
425
      /*
 
426
        When the following assert starts failing, we'll have to switch
 
427
        to the upper branch of the #ifdef
 
428
      */
 
429
      assert(min_plugin_interface_version == 0);
 
430
      sizeof_st_plugin= (int)offsetof(struct st_mysql_plugin, version);
 
431
#endif
 
432
    }
 
433
 
 
434
    for (i= 0;
 
435
         ((struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
 
436
         i++)
 
437
      /* no op */;
 
438
 
 
439
    cur= (struct st_mysql_plugin*)
 
440
          my_malloc(i*sizeof(struct st_mysql_plugin), MYF(MY_ZEROFILL|MY_WME));
 
441
    if (!cur)
 
442
    {
 
443
      free_plugin_mem(&plugin_dl);
 
444
      if (report & REPORT_TO_USER)
 
445
        my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length);
 
446
      if (report & REPORT_TO_LOG)
 
447
        sql_print_error(ER(ER_OUTOFMEMORY), plugin_dl.dl.length);
 
448
      return(0);
 
449
    }
 
450
    /*
 
451
      All st_plugin fields not initialized in the plugin explicitly, are
 
452
      set to 0. It matches C standard behaviour for struct initializers that
 
453
      have less values than the struct definition.
 
454
    */
 
455
    for (i=0;
 
456
         (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
 
457
         i++)
 
458
      memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
 
459
 
 
460
    sym= cur;
 
461
  }
373
462
  plugin_dl.plugins= (struct st_mysql_plugin *)sym;
374
463
 
375
464
  /* Duplicate and convert dll name */
398
487
    return(0);
399
488
  }
400
489
  return(tmp);
 
490
#else
 
491
  if (report & REPORT_TO_USER)
 
492
    my_error(ER_FEATURE_DISABLED, MYF(0), "plugin", "HAVE_DLOPEN");
 
493
  if (report & REPORT_TO_LOG)
 
494
    sql_print_error(ER(ER_FEATURE_DISABLED), "plugin", "HAVE_DLOPEN");
 
495
  return(0);
 
496
#endif
401
497
}
402
498
 
403
499
 
404
500
static void plugin_dl_del(const LEX_STRING *dl)
405
501
{
406
 
  uint32_t i;
 
502
#ifdef HAVE_DLOPEN
 
503
  uint i;
407
504
 
408
505
  for (i= 0; i < plugin_dl_array.elements; i++)
409
506
  {
411
508
                                               struct st_plugin_dl **);
412
509
    if (tmp->ref_count &&
413
510
        ! my_strnncoll(files_charset_info,
414
 
                       (const unsigned char *)dl->str, dl->length,
415
 
                       (const unsigned char *)tmp->dl.str, tmp->dl.length))
 
511
                       (const uchar *)dl->str, dl->length,
 
512
                       (const uchar *)tmp->dl.str, tmp->dl.length))
416
513
    {
417
514
      /* Do not remove this element, unless no other plugin uses this dll. */
418
515
      if (! --tmp->ref_count)
419
516
      {
420
517
        free_plugin_mem(tmp);
421
 
        memset(tmp, 0, sizeof(struct st_plugin_dl));
 
518
        bzero(tmp, sizeof(struct st_plugin_dl));
422
519
      }
423
520
      break;
424
521
    }
425
522
  }
426
523
  return;
 
524
#endif
427
525
}
428
526
 
429
527
 
430
528
static struct st_plugin_int *plugin_find_internal(const LEX_STRING *name, int type)
431
529
{
432
 
  uint32_t i;
 
530
  uint i;
433
531
  if (! initialized)
434
532
    return(0);
435
533
 
436
 
  if (type == DRIZZLE_ANY_PLUGIN)
 
534
  if (type == MYSQL_ANY_PLUGIN)
437
535
  {
438
 
    for (i= 0; i < DRIZZLE_MAX_PLUGIN_TYPE_NUM; i++)
 
536
    for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++)
439
537
    {
440
538
      struct st_plugin_int *plugin= (st_plugin_int *)
441
 
        hash_search(&plugin_hash[i], (const unsigned char *)name->str, name->length);
 
539
        hash_search(&plugin_hash[i], (const uchar *)name->str, name->length);
442
540
      if (plugin)
443
541
        return(plugin);
444
542
    }
445
543
  }
446
544
  else
447
545
    return((st_plugin_int *)
448
 
        hash_search(&plugin_hash[type], (const unsigned char *)name->str, name->length));
 
546
        hash_search(&plugin_hash[type], (const uchar *)name->str, name->length));
449
547
  return(0);
450
548
}
451
549
 
466
564
 
467
565
bool plugin_is_ready(const LEX_STRING *name, int type)
468
566
{
469
 
  bool rc= false;
 
567
  bool rc= FALSE;
470
568
  if (plugin_status(name, type) == SHOW_OPTION_YES)
471
 
    rc= true;
 
569
    rc= TRUE;
472
570
  return rc;
473
571
}
474
572
 
499
597
    pi->ref_count++;
500
598
 
501
599
    if (lex)
502
 
      insert_dynamic(&lex->plugins, (unsigned char*)&plugin);
 
600
      insert_dynamic(&lex->plugins, (uchar*)&plugin);
503
601
    return(plugin);
504
602
  }
505
603
  return(NULL);
529
627
 
530
628
static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin)
531
629
{
532
 
  uint32_t i;
 
630
  uint i;
533
631
  struct st_plugin_int *tmp;
534
632
  for (i= 0; i < plugin_array.elements; i++)
535
633
  {
540
638
      return(tmp);
541
639
    }
542
640
  }
543
 
  if (insert_dynamic(&plugin_array, (unsigned char*)&plugin))
 
641
  if (insert_dynamic(&plugin_array, (uchar*)&plugin))
544
642
    return(0);
545
643
  tmp= *dynamic_element(&plugin_array, plugin_array.elements - 1,
546
644
                        struct st_plugin_int **)=
547
 
       (struct st_plugin_int *) memdup_root(&plugin_mem_root, (unsigned char*)plugin,
 
645
       (struct st_plugin_int *) memdup_root(&plugin_mem_root, (uchar*)plugin,
548
646
                                            sizeof(struct st_plugin_int));
549
647
  return(tmp);
550
648
}
560
658
{
561
659
  struct st_plugin_int tmp;
562
660
  struct st_mysql_plugin *plugin;
563
 
  if (plugin_find_internal(name, DRIZZLE_ANY_PLUGIN))
 
661
  if (plugin_find_internal(name, MYSQL_ANY_PLUGIN))
564
662
  {
565
663
    if (report & REPORT_TO_USER)
566
664
      my_error(ER_UDF_EXISTS, MYF(0), name->str);
567
665
    if (report & REPORT_TO_LOG)
568
666
      sql_print_error(ER(ER_UDF_EXISTS), name->str);
569
 
    return(true);
 
667
    return(TRUE);
570
668
  }
571
669
  /* Clear the whole struct to catch future extensions. */
572
 
  memset(&tmp, 0, sizeof(tmp));
 
670
  bzero((char*) &tmp, sizeof(tmp));
573
671
  if (! (tmp.plugin_dl= plugin_dl_add(dl, report)))
574
 
    return(true);
 
672
    return(TRUE);
575
673
  /* Find plugin by name */
576
 
  for (plugin= tmp.plugin_dl->plugins; plugin->name; plugin++)
 
674
  for (plugin= tmp.plugin_dl->plugins; plugin->info; plugin++)
577
675
  {
578
 
    uint32_t name_len= strlen(plugin->name);
579
 
    if (plugin->type >= 0 && plugin->type < DRIZZLE_MAX_PLUGIN_TYPE_NUM &&
 
676
    uint name_len= strlen(plugin->name);
 
677
    if (plugin->type >= 0 && plugin->type < MYSQL_MAX_PLUGIN_TYPE_NUM &&
580
678
        ! my_strnncoll(system_charset_info,
581
 
                       (const unsigned char *)name->str, name->length,
582
 
                       (const unsigned char *)plugin->name,
 
679
                       (const uchar *)name->str, name->length,
 
680
                       (const uchar *)plugin->name,
583
681
                       name_len))
584
682
    {
585
683
      struct st_plugin_int *tmp_plugin_ptr;
586
 
 
 
684
      if (*(int*)plugin->info <
 
685
          min_plugin_info_interface_version[plugin->type] ||
 
686
          ((*(int*)plugin->info) >> 8) >
 
687
          (cur_plugin_info_interface_version[plugin->type] >> 8))
 
688
      {
 
689
        char buf[256];
 
690
        strxnmov(buf, sizeof(buf) - 1, "API version for ",
 
691
                 plugin_type_names[plugin->type].str,
 
692
                 " plugin is too different", NullS);
 
693
        if (report & REPORT_TO_USER)
 
694
          my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dl->str, 0, buf);
 
695
        if (report & REPORT_TO_LOG)
 
696
          sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dl->str, 0, buf);
 
697
        goto err;
 
698
      }
587
699
      tmp.plugin= plugin;
588
700
      tmp.name.str= (char *)plugin->name;
589
701
      tmp.name.length= name_len;
590
702
      tmp.ref_count= 0;
591
703
      tmp.state= PLUGIN_IS_UNINITIALIZED;
592
 
      if (!test_plugin_options(tmp_root, &tmp, argc, argv))
 
704
      if (!test_plugin_options(tmp_root, &tmp, argc, argv, true))
593
705
      {
594
706
        if ((tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
595
707
        {
596
708
          plugin_array_version++;
597
 
          if (!my_hash_insert(&plugin_hash[plugin->type], (unsigned char*)tmp_plugin_ptr))
 
709
          if (!my_hash_insert(&plugin_hash[plugin->type], (uchar*)tmp_plugin_ptr))
598
710
          {
599
711
            init_alloc_root(&tmp_plugin_ptr->mem_root, 4096, 4096);
600
 
            return(false);
 
712
            return(FALSE);
601
713
          }
602
714
          tmp_plugin_ptr->state= PLUGIN_IS_FREED;
603
715
        }
606
718
      }
607
719
      /* plugin was disabled */
608
720
      plugin_dl_del(dl);
609
 
      return(false);
 
721
      return(FALSE);
610
722
    }
611
723
  }
612
724
  if (report & REPORT_TO_USER)
615
727
    sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), name->str);
616
728
err:
617
729
  plugin_dl_del(dl);
618
 
  return(true);
 
730
  return(TRUE);
619
731
}
620
732
 
621
733
 
645
757
  {
646
758
    if ((*plugin_type_deinitialize[plugin->plugin->type])(plugin))
647
759
    {
648
 
      sql_print_error(_("Plugin '%s' of type %s failed deinitialization"),
 
760
      sql_print_error("Plugin '%s' of type %s failed deinitialization",
649
761
                      plugin->name.str, plugin_type_names[plugin->plugin->type].str);
650
762
    }
651
763
  }
659
771
    exit until NDB is shut down.
660
772
  */
661
773
  if (ref_check && plugin->ref_count)
662
 
    sql_print_error(_("Plugin '%s' has ref_count=%d after deinitialization."),
 
774
    sql_print_error("Plugin '%s' has ref_count=%d after deinitialization.",
663
775
                    plugin->name.str, plugin->ref_count);
664
776
}
665
777
 
668
780
{
669
781
  /* Free allocated strings before deleting the plugin. */
670
782
  plugin_vars_free_values(plugin->system_vars);
671
 
  hash_delete(&plugin_hash[plugin->plugin->type], (unsigned char*)plugin);
 
783
  hash_delete(&plugin_hash[plugin->plugin->type], (uchar*)plugin);
672
784
  if (plugin->plugin_dl)
673
785
    plugin_dl_del(&plugin->plugin_dl->dl);
674
786
  plugin->state= PLUGIN_IS_FREED;
680
792
  return;
681
793
}
682
794
 
 
795
#ifdef NOT_USED
 
796
 
 
797
static void plugin_del(const LEX_STRING *name)
 
798
{
 
799
  struct st_plugin_int *plugin;
 
800
  if ((plugin= plugin_find_internal(name, MYSQL_ANY_PLUGIN)))
 
801
    plugin_del(plugin);
 
802
  return;
 
803
}
 
804
 
 
805
#endif
 
806
 
683
807
static void reap_plugins(void)
684
808
{
685
 
  uint32_t count, idx;
 
809
  uint count, idx;
686
810
  struct st_plugin_int *plugin, **reap, **list;
687
811
 
688
812
  if (!reap_needed)
724
848
 
725
849
  pi= plugin_ref_to_int(plugin);
726
850
 
727
 
  free((unsigned char*) plugin);
 
851
  my_free((uchar*) plugin, MYF(MY_WME));
728
852
 
729
853
  if (lex)
730
854
  {
758
882
  if (!plugin)
759
883
    return;
760
884
  intern_plugin_unlock(lex, plugin);
 
885
  reap_plugins();
761
886
  return;
762
887
}
763
888
 
764
889
 
765
 
void plugin_unlock_list(THD *thd, plugin_ref *list, uint32_t count)
 
890
void plugin_unlock_list(THD *thd, plugin_ref *list, uint count)
766
891
{
767
892
  LEX *lex= thd ? thd->lex : 0;
768
893
  assert(list);
769
894
  while (count--)
770
895
    intern_plugin_unlock(lex, *list++);
 
896
  reap_plugins();
771
897
  return;
772
898
}
773
899
 
779
905
  {
780
906
    if ((*plugin_type_initialize[plugin->plugin->type])(plugin))
781
907
    {
782
 
      sql_print_error(_("Plugin '%s' registration as a %s failed."),
 
908
      sql_print_error("Plugin '%s' registration as a %s failed.",
783
909
                      plugin->name.str, plugin_type_names[plugin->plugin->type].str);
784
910
      goto err;
785
911
    }
788
914
  {
789
915
    if (plugin->plugin->init(plugin))
790
916
    {
791
 
      sql_print_error(_("Plugin '%s' init function returned error."),
 
917
      sql_print_error("Plugin '%s' init function returned error.",
792
918
                      plugin->name.str);
793
919
      goto err;
794
920
    }
839
965
}
840
966
 
841
967
 
842
 
extern "C" unsigned char *get_plugin_hash_key(const unsigned char *, size_t *, bool);
843
 
extern "C" unsigned char *get_bookmark_hash_key(const unsigned char *, size_t *, bool);
844
 
 
845
 
 
846
 
unsigned char *get_plugin_hash_key(const unsigned char *buff, size_t *length,
847
 
                           bool not_used __attribute__((unused)))
 
968
extern "C" uchar *get_plugin_hash_key(const uchar *, size_t *, my_bool);
 
969
extern "C" uchar *get_bookmark_hash_key(const uchar *, size_t *, my_bool);
 
970
 
 
971
 
 
972
uchar *get_plugin_hash_key(const uchar *buff, size_t *length,
 
973
                           my_bool not_used __attribute__((unused)))
848
974
{
849
975
  struct st_plugin_int *plugin= (st_plugin_int *)buff;
850
976
  *length= (uint)plugin->name.length;
851
 
  return((unsigned char *)plugin->name.str);
 
977
  return((uchar *)plugin->name.str);
852
978
}
853
979
 
854
980
 
855
 
unsigned char *get_bookmark_hash_key(const unsigned char *buff, size_t *length,
856
 
                             bool not_used __attribute__((unused)))
 
981
uchar *get_bookmark_hash_key(const uchar *buff, size_t *length,
 
982
                             my_bool not_used __attribute__((unused)))
857
983
{
858
984
  struct st_bookmark *var= (st_bookmark *)buff;
859
985
  *length= var->name_len + 1;
860
 
  return (unsigned char*) var->key;
 
986
  return (uchar*) var->key;
861
987
}
862
988
 
863
989
 
870
996
*/
871
997
int plugin_init(int *argc, char **argv, int flags)
872
998
{
873
 
  uint32_t i;
 
999
  uint i;
 
1000
  bool def_enabled, is_myisam;
874
1001
  struct st_mysql_plugin **builtins;
875
1002
  struct st_mysql_plugin *plugin;
876
1003
  struct st_plugin_int tmp, *plugin_ptr, **reap;
893
1020
                            sizeof(struct st_plugin_int *),16,16))
894
1021
    goto err;
895
1022
 
896
 
  for (i= 0; i < DRIZZLE_MAX_PLUGIN_TYPE_NUM; i++)
 
1023
  for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++)
897
1024
  {
898
1025
    if (hash_init(&plugin_hash[i], system_charset_info, 16, 0, 0,
899
1026
                  get_plugin_hash_key, NULL, HASH_UNIQUE))
907
1034
  */
908
1035
  for (builtins= mysqld_builtins; *builtins; builtins++)
909
1036
  {
910
 
    for (plugin= *builtins; plugin->name; plugin++)
 
1037
    for (plugin= *builtins; plugin->info; plugin++)
911
1038
    {
912
 
      memset(&tmp, 0, sizeof(tmp));
 
1039
      /* by default, only ndbcluster is disabled */
 
1040
      def_enabled=
 
1041
        my_strcasecmp(&my_charset_latin1, plugin->name, "NDBCLUSTER") != 0;
 
1042
      bzero(&tmp, sizeof(tmp));
913
1043
      tmp.plugin= plugin;
914
1044
      tmp.name.str= (char *)plugin->name;
915
1045
      tmp.name.length= strlen(plugin->name);
916
1046
 
917
1047
      free_root(&tmp_root, MYF(MY_MARK_BLOCKS_FREE));
918
 
      if (test_plugin_options(&tmp_root, &tmp, argc, argv))
 
1048
      if (test_plugin_options(&tmp_root, &tmp, argc, argv, def_enabled))
919
1049
        continue;
920
1050
 
921
1051
      if (register_builtin(plugin, &tmp, &plugin_ptr))
922
1052
        goto err_unlock;
923
1053
 
 
1054
      /* only initialize MyISAM and CSV at this stage */
 
1055
      if (!(is_myisam=
 
1056
            !my_strcasecmp(&my_charset_latin1, plugin->name, "MyISAM")) &&
 
1057
          my_strcasecmp(&my_charset_latin1, plugin->name, "CSV"))
 
1058
        continue;
 
1059
 
924
1060
      if (plugin_initialize(plugin_ptr))
925
1061
        goto err_unlock;
926
1062
 
928
1064
        initialize the global default storage engine so that it may
929
1065
        not be null in any child thread.
930
1066
      */
931
 
      if (my_strcasecmp(&my_charset_utf8_general_ci, plugin->name, "MyISAM") == 0)
 
1067
      if (is_myisam)
932
1068
      {
933
1069
        assert(!global_system_variables.table_plugin);
934
1070
        global_system_variables.table_plugin=
1003
1139
  tmp->ref_count= 0;
1004
1140
  tmp->plugin_dl= 0;
1005
1141
 
1006
 
  if (insert_dynamic(&plugin_array, (unsigned char*)&tmp))
 
1142
  if (insert_dynamic(&plugin_array, (uchar*)&tmp))
1007
1143
    return(1);
1008
1144
 
1009
1145
  *ptr= *dynamic_element(&plugin_array, plugin_array.elements - 1,
1010
1146
                         struct st_plugin_int **)=
1011
 
        (struct st_plugin_int *) memdup_root(&plugin_mem_root, (unsigned char*)tmp,
 
1147
        (struct st_plugin_int *) memdup_root(&plugin_mem_root, (uchar*)tmp,
1012
1148
                                             sizeof(struct st_plugin_int));
1013
1149
 
1014
 
  if (my_hash_insert(&plugin_hash[plugin->type],(unsigned char*) *ptr))
 
1150
  if (my_hash_insert(&plugin_hash[plugin->type],(uchar*) *ptr))
1015
1151
    return(1);
1016
1152
 
1017
1153
  return(0);
1018
1154
}
1019
1155
 
1020
1156
 
 
1157
#ifdef NOT_USED_YET
 
1158
/*
 
1159
  Register a plugin at run time. (note, this doesn't initialize a plugin)
 
1160
  Will be useful for embedded applications.
 
1161
 
 
1162
  SYNOPSIS
 
1163
    plugin_register_builtin()
 
1164
    thd         current thread (used to store scratch data in mem_root)
 
1165
    plugin      static plugin to install
 
1166
 
 
1167
  RETURN
 
1168
    false - plugin registered successfully
 
1169
*/
 
1170
bool plugin_register_builtin(THD *thd, struct st_mysql_plugin *plugin)
 
1171
{
 
1172
  struct st_plugin_int tmp, *ptr;
 
1173
  bool result= true;
 
1174
  int dummy_argc= 0;
 
1175
 
 
1176
  bzero(&tmp, sizeof(tmp));
 
1177
  tmp.plugin= plugin;
 
1178
  tmp.name.str= (char *)plugin->name;
 
1179
  tmp.name.length= strlen(plugin->name);
 
1180
 
 
1181
  rw_wrlock(&LOCK_system_variables_hash);
 
1182
 
 
1183
  if (test_plugin_options(thd->mem_root, &tmp, &dummy_argc, NULL, true))
 
1184
    goto end;
 
1185
 
 
1186
  if ((result= register_builtin(plugin, &tmp, &ptr)))
 
1187
    mysql_del_sys_var_chain(tmp.system_vars);
 
1188
 
 
1189
end:
 
1190
  rw_unlock(&LOCK_system_variables_hash);
 
1191
 
 
1192
  return(result);;
 
1193
}
 
1194
#endif /* NOT_USED_YET */
 
1195
 
 
1196
 
1021
1197
/*
1022
1198
  called only by plugin_init()
1023
1199
*/
1033
1209
  {
1034
1210
    if (p == buffer + sizeof(buffer) - 1)
1035
1211
    {
1036
 
      sql_print_error(_("plugin-load parameter too long"));
1037
 
      return(true);
 
1212
      sql_print_error("plugin-load parameter too long");
 
1213
      return(TRUE);
1038
1214
    }
1039
1215
 
1040
1216
    switch ((*(p++)= *(list++))) {
1055
1231
        dl= name;
1056
1232
        if ((plugin_dl= plugin_dl_add(&dl, REPORT_TO_LOG)))
1057
1233
        {
1058
 
          for (plugin= plugin_dl->plugins; plugin->name; plugin++)
 
1234
          for (plugin= plugin_dl->plugins; plugin->info; plugin++)
1059
1235
          {
1060
1236
            name.str= (char *) plugin->name;
1061
1237
            name.length= strlen(name.str);
1091
1267
      continue;
1092
1268
    }
1093
1269
  }
1094
 
  return(false);
 
1270
  return(FALSE);
1095
1271
error:
1096
 
  sql_print_error(_("Couldn't load plugin named '%s' with soname '%s'."),
 
1272
  sql_print_error("Couldn't load plugin named '%s' with soname '%s'.",
1097
1273
                  name.str, dl.str);
1098
 
  return(true);
 
1274
  return(TRUE);
1099
1275
}
1100
1276
 
1101
1277
 
1102
1278
void plugin_shutdown(void)
1103
1279
{
1104
 
  uint32_t i, count= plugin_array.elements, free_slots= 0;
 
1280
  uint i, count= plugin_array.elements, free_slots= 0;
1105
1281
  struct st_plugin_int **plugins, *plugin;
1106
1282
  struct st_plugin_dl **dl;
1107
1283
 
1144
1320
    }
1145
1321
 
1146
1322
    if (count > free_slots)
1147
 
      sql_print_warning(_("Forcing shutdown of %d plugins"),
1148
 
                        count - free_slots);
 
1323
      sql_print_warning("Forcing shutdown of %d plugins", count - free_slots);
1149
1324
 
1150
1325
    plugins= (struct st_plugin_int **) my_alloca(sizeof(void*) * (count+1));
1151
1326
 
1166
1341
    for (i= 0; i < count; i++)
1167
1342
      if (!(plugins[i]->state & (PLUGIN_IS_UNINITIALIZED | PLUGIN_IS_FREED)))
1168
1343
      {
1169
 
        sql_print_information(_("Plugin '%s' will be forced to shutdown"),
 
1344
        sql_print_information("Plugin '%s' will be forced to shutdown",
1170
1345
                              plugins[i]->name.str);
1171
1346
        /*
1172
1347
          We are forcing deinit on plugins so we don't want to do a ref_count
1182
1357
    for (i= 0; i < count; i++)
1183
1358
    {
1184
1359
      if (plugins[i]->ref_count)
1185
 
        sql_print_error(_("Plugin '%s' has ref_count=%d after shutdown."),
 
1360
        sql_print_error("Plugin '%s' has ref_count=%d after shutdown.",
1186
1361
                        plugins[i]->name.str, plugins[i]->ref_count);
1187
1362
      if (plugins[i]->state & PLUGIN_IS_UNINITIALIZED)
1188
1363
        plugin_del(plugins[i]);
1202
1377
 
1203
1378
  /* Dispose of the memory */
1204
1379
 
1205
 
  for (i= 0; i < DRIZZLE_MAX_PLUGIN_TYPE_NUM; i++)
 
1380
  for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++)
1206
1381
    hash_free(&plugin_hash[i]);
1207
1382
  delete_dynamic(&plugin_array);
1208
1383
 
1225
1400
 
1226
1401
 
1227
1402
bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func,
1228
 
                       int type, uint32_t state_mask, void *arg)
 
1403
                       int type, uint state_mask, void *arg)
1229
1404
{
1230
 
  uint32_t idx, total;
 
1405
  uint idx, total;
1231
1406
  struct st_plugin_int *plugin, **plugins;
1232
1407
  int version=plugin_array_version;
1233
1408
 
1234
1409
  if (!initialized)
1235
 
    return(false);
 
1410
    return(FALSE);
1236
1411
 
1237
1412
  state_mask= ~state_mask; // do it only once
1238
1413
 
1239
 
  total= type == DRIZZLE_ANY_PLUGIN ? plugin_array.elements
 
1414
  total= type == MYSQL_ANY_PLUGIN ? plugin_array.elements
1240
1415
                                  : plugin_hash[type].records;
1241
1416
  /*
1242
1417
    Do the alloca out here in case we do have a working alloca:
1243
1418
        leaving the nested stack frame invalidates alloca allocation.
1244
1419
  */
1245
1420
  plugins=(struct st_plugin_int **)my_alloca(total*sizeof(plugin));
1246
 
  if (type == DRIZZLE_ANY_PLUGIN)
 
1421
  if (type == MYSQL_ANY_PLUGIN)
1247
1422
  {
1248
1423
    for (idx= 0; idx < total; idx++)
1249
1424
    {
1264
1439
  {
1265
1440
    if (unlikely(version != plugin_array_version))
1266
1441
    {
1267
 
      for (uint32_t i=idx; i < total; i++)
 
1442
      for (uint i=idx; i < total; i++)
1268
1443
        if (plugins[i] && plugins[i]->state & state_mask)
1269
1444
          plugins[i]=0;
1270
1445
    }
1271
1446
    plugin= plugins[idx];
1272
 
    /* It will stop iterating on first engine error when "func" returns true */
 
1447
    /* It will stop iterating on first engine error when "func" returns TRUE */
1273
1448
    if (plugin && func(thd, plugin_int_to_ref(plugin), arg))
1274
1449
        goto err;
1275
1450
  }
1276
1451
 
1277
1452
  my_afree(plugins);
1278
 
  return(false);
 
1453
  return(FALSE);
1279
1454
err:
1280
1455
  my_afree(plugins);
1281
 
  return(true);
 
1456
  return(TRUE);
1282
1457
}
1283
1458
 
1284
1459
 
1286
1461
  Internal type declarations for variables support
1287
1462
****************************************************************************/
1288
1463
 
1289
 
#undef DRIZZLE_SYSVAR_NAME
1290
 
#define DRIZZLE_SYSVAR_NAME(name) name
 
1464
#undef MYSQL_SYSVAR_NAME
 
1465
#define MYSQL_SYSVAR_NAME(name) name
1291
1466
#define PLUGIN_VAR_TYPEMASK 0x007f
1292
1467
 
1293
1468
#define EXTRA_OPTIONS 3 /* options for: 'foo', 'plugin-foo' and NULL */
1294
1469
 
1295
 
typedef DECLARE_DRIZZLE_SYSVAR_BASIC(sysvar_bool_t, bool);
1296
 
typedef DECLARE_DRIZZLE_THDVAR_BASIC(thdvar_bool_t, bool);
1297
 
typedef DECLARE_DRIZZLE_SYSVAR_BASIC(sysvar_str_t, char *);
1298
 
typedef DECLARE_DRIZZLE_THDVAR_BASIC(thdvar_str_t, char *);
1299
 
 
1300
 
typedef DECLARE_DRIZZLE_SYSVAR_TYPELIB(sysvar_enum_t, unsigned long);
1301
 
typedef DECLARE_DRIZZLE_THDVAR_TYPELIB(thdvar_enum_t, unsigned long);
1302
 
typedef DECLARE_DRIZZLE_SYSVAR_TYPELIB(sysvar_set_t, uint64_t);
1303
 
typedef DECLARE_DRIZZLE_THDVAR_TYPELIB(thdvar_set_t, uint64_t);
1304
 
 
1305
 
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_int_t, int);
1306
 
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_long_t, long);
1307
 
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_int64_t_t, int64_t);
1308
 
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_uint_t, uint);
1309
 
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_ulong_t, ulong);
1310
 
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_uint64_t_t, uint64_t);
1311
 
 
1312
 
typedef DECLARE_DRIZZLE_THDVAR_SIMPLE(thdvar_int_t, int);
1313
 
typedef DECLARE_DRIZZLE_THDVAR_SIMPLE(thdvar_long_t, long);
1314
 
typedef DECLARE_DRIZZLE_THDVAR_SIMPLE(thdvar_int64_t_t, int64_t);
1315
 
typedef DECLARE_DRIZZLE_THDVAR_SIMPLE(thdvar_uint_t, uint);
1316
 
typedef DECLARE_DRIZZLE_THDVAR_SIMPLE(thdvar_ulong_t, ulong);
1317
 
typedef DECLARE_DRIZZLE_THDVAR_SIMPLE(thdvar_uint64_t_t, uint64_t);
1318
 
 
1319
 
typedef bool *(*mysql_sys_var_ptr_p)(THD* a_thd, int offset);
 
1470
typedef DECLARE_MYSQL_SYSVAR_BASIC(sysvar_bool_t, my_bool);
 
1471
typedef DECLARE_MYSQL_THDVAR_BASIC(thdvar_bool_t, my_bool);
 
1472
typedef DECLARE_MYSQL_SYSVAR_BASIC(sysvar_str_t, char *);
 
1473
typedef DECLARE_MYSQL_THDVAR_BASIC(thdvar_str_t, char *);
 
1474
 
 
1475
typedef DECLARE_MYSQL_SYSVAR_TYPELIB(sysvar_enum_t, unsigned long);
 
1476
typedef DECLARE_MYSQL_THDVAR_TYPELIB(thdvar_enum_t, unsigned long);
 
1477
typedef DECLARE_MYSQL_SYSVAR_TYPELIB(sysvar_set_t, ulonglong);
 
1478
typedef DECLARE_MYSQL_THDVAR_TYPELIB(thdvar_set_t, ulonglong);
 
1479
 
 
1480
typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_int_t, int);
 
1481
typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_long_t, long);
 
1482
typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_longlong_t, longlong);
 
1483
typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_uint_t, uint);
 
1484
typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_ulong_t, ulong);
 
1485
typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_ulonglong_t, ulonglong);
 
1486
 
 
1487
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_int_t, int);
 
1488
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_long_t, long);
 
1489
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_longlong_t, longlong);
 
1490
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_uint_t, uint);
 
1491
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_ulong_t, ulong);
 
1492
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_ulonglong_t, ulonglong);
 
1493
 
 
1494
#define SET_PLUGIN_VAR_RESOLVE(opt)\
 
1495
  *(mysql_sys_var_ptr_p*)&((opt)->resolve)= mysql_sys_var_ptr
 
1496
typedef uchar *(*mysql_sys_var_ptr_p)(void* a_thd, int offset);
1320
1497
 
1321
1498
 
1322
1499
/****************************************************************************
1323
1500
  default variable data check and update functions
1324
1501
****************************************************************************/
1325
1502
 
1326
 
static int check_func_bool(THD *thd __attribute__((unused)),
 
1503
static int check_func_bool(THD *thd __attribute__((__unused__)),
1327
1504
                           struct st_mysql_sys_var *var,
1328
1505
                           void *save, st_mysql_value *value)
1329
1506
{
1332
1509
  int result, length;
1333
1510
  int64_t tmp;
1334
1511
 
1335
 
  if (value->value_type(value) == DRIZZLE_VALUE_TYPE_STRING)
 
1512
  if (value->value_type(value) == MYSQL_VALUE_TYPE_STRING)
1336
1513
  {
1337
1514
    length= sizeof(buff);
1338
1515
    if (!(str= value->val_str(value, buff, &length)) ||
1366
1543
static int check_func_int(THD *thd, struct st_mysql_sys_var *var,
1367
1544
                          void *save, st_mysql_value *value)
1368
1545
{
1369
 
  bool fixed;
 
1546
  my_bool fixed;
1370
1547
  int64_t tmp;
1371
1548
  struct my_option options;
1372
1549
  value->val_int(value, &tmp);
1373
1550
  plugin_opt_set_limits(&options, var);
1374
1551
 
1375
1552
  if (var->flags & PLUGIN_VAR_UNSIGNED)
1376
 
    *(uint32_t *)save= (uint) getopt_ull_limit_value((uint64_t) tmp, &options,
 
1553
    *(uint *)save= (uint) getopt_ull_limit_value((ulonglong) tmp, &options,
1377
1554
                                                   &fixed);
1378
1555
  else
1379
1556
    *(int *)save= (int) getopt_ll_limit_value(tmp, &options, &fixed);
1380
1557
 
1381
1558
  return throw_bounds_warning(thd, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
1382
 
                              var->name, (int64_t) tmp);
 
1559
                              var->name, (longlong) tmp);
1383
1560
}
1384
1561
 
1385
1562
 
1386
1563
static int check_func_long(THD *thd, struct st_mysql_sys_var *var,
1387
1564
                          void *save, st_mysql_value *value)
1388
1565
{
1389
 
  bool fixed;
 
1566
  my_bool fixed;
1390
1567
  int64_t tmp;
1391
1568
  struct my_option options;
1392
1569
  value->val_int(value, &tmp);
1393
1570
  plugin_opt_set_limits(&options, var);
1394
1571
 
1395
1572
  if (var->flags & PLUGIN_VAR_UNSIGNED)
1396
 
    *(ulong *)save= (ulong) getopt_ull_limit_value((uint64_t) tmp, &options,
 
1573
    *(ulong *)save= (ulong) getopt_ull_limit_value((ulonglong) tmp, &options,
1397
1574
                                                   &fixed);
1398
1575
  else
1399
1576
    *(long *)save= (long) getopt_ll_limit_value(tmp, &options, &fixed);
1400
1577
 
1401
1578
  return throw_bounds_warning(thd, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
1402
 
                              var->name, (int64_t) tmp);
 
1579
                              var->name, (longlong) tmp);
1403
1580
}
1404
1581
 
1405
1582
 
1406
 
static int check_func_int64_t(THD *thd, struct st_mysql_sys_var *var,
 
1583
static int check_func_longlong(THD *thd, struct st_mysql_sys_var *var,
1407
1584
                               void *save, st_mysql_value *value)
1408
1585
{
1409
 
  bool fixed;
 
1586
  my_bool fixed;
1410
1587
  int64_t tmp;
1411
1588
  struct my_option options;
1412
1589
  value->val_int(value, &tmp);
1413
1590
  plugin_opt_set_limits(&options, var);
1414
1591
 
1415
1592
  if (var->flags & PLUGIN_VAR_UNSIGNED)
1416
 
    *(uint64_t *)save= getopt_ull_limit_value((uint64_t) tmp, &options,
 
1593
    *(ulonglong *)save= getopt_ull_limit_value((ulonglong) tmp, &options,
1417
1594
                                               &fixed);
1418
1595
  else
1419
 
    *(int64_t *)save= getopt_ll_limit_value(tmp, &options, &fixed);
 
1596
    *(longlong *)save= getopt_ll_limit_value(tmp, &options, &fixed);
1420
1597
 
1421
1598
  return throw_bounds_warning(thd, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
1422
 
                              var->name, (int64_t) tmp);
 
1599
                              var->name, (longlong) tmp);
1423
1600
}
1424
1601
 
1425
1602
static int check_func_str(THD *thd,
1426
 
                          struct st_mysql_sys_var *var __attribute__((unused)),
 
1603
                          struct st_mysql_sys_var *var __attribute__((__unused__)),
1427
1604
                          void *save, st_mysql_value *value)
1428
1605
{
1429
1606
  char buff[STRING_BUFFER_USUAL_SIZE];
1438
1615
}
1439
1616
 
1440
1617
 
1441
 
static int check_func_enum(THD *thd __attribute__((unused)),
 
1618
static int check_func_enum(THD *thd __attribute__((__unused__)),
1442
1619
                           struct st_mysql_sys_var *var,
1443
1620
                           void *save, st_mysql_value *value)
1444
1621
{
1454
1631
  else
1455
1632
    typelib= ((sysvar_enum_t*) var)->typelib;
1456
1633
 
1457
 
  if (value->value_type(value) == DRIZZLE_VALUE_TYPE_STRING)
 
1634
  if (value->value_type(value) == MYSQL_VALUE_TYPE_STRING)
1458
1635
  {
1459
1636
    length= sizeof(buff);
1460
1637
    if (!(str= value->val_str(value, buff, &length)))
1485
1662
}
1486
1663
 
1487
1664
 
1488
 
static int check_func_set(THD *thd __attribute__((unused)),
 
1665
static int check_func_set(THD *thd __attribute__((__unused__)),
1489
1666
                          struct st_mysql_sys_var *var,
1490
1667
                          void *save, st_mysql_value *value)
1491
1668
{
1492
1669
  char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
1493
1670
  const char *strvalue= "NULL", *str;
1494
1671
  TYPELIB *typelib;
1495
 
  uint64_t result;
1496
 
  uint32_t error_len;
 
1672
  ulonglong result;
 
1673
  uint error_len;
1497
1674
  bool not_used;
1498
1675
  int length;
1499
1676
 
1502
1679
  else
1503
1680
    typelib= ((sysvar_set_t*)var)->typelib;
1504
1681
 
1505
 
  if (value->value_type(value) == DRIZZLE_VALUE_TYPE_STRING)
 
1682
  if (value->value_type(value) == MYSQL_VALUE_TYPE_STRING)
1506
1683
  {
1507
1684
    length= sizeof(buff);
1508
1685
    if (!(str= value->val_str(value, buff, &length)))
1511
1688
                     &error, &error_len, &not_used);
1512
1689
    if (error_len)
1513
1690
    {
1514
 
      strmake(buff, error, cmin(sizeof(buff), (unsigned long)error_len));
 
1691
      strmake(buff, error, min(sizeof(buff), error_len));
1515
1692
      strvalue= buff;
1516
1693
      goto err;
1517
1694
    }
1520
1697
  {
1521
1698
    if (value->val_int(value, (int64_t *)&result))
1522
1699
      goto err;
1523
 
    if (unlikely((result >= (1UL << typelib->count)) &&
 
1700
    if (unlikely((result >= (1ULL << typelib->count)) &&
1524
1701
                 (typelib->count < sizeof(long)*8)))
1525
1702
    {
1526
1703
      llstr(result, buff);
1528
1705
      goto err;
1529
1706
    }
1530
1707
  }
1531
 
  *(uint64_t*)save= result;
 
1708
  *(ulonglong*)save= result;
1532
1709
  return 0;
1533
1710
err:
1534
1711
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
1536
1713
}
1537
1714
 
1538
1715
 
1539
 
static void update_func_bool(THD *thd __attribute__((unused)),
1540
 
                             struct st_mysql_sys_var *var __attribute__((unused)),
 
1716
static void update_func_bool(THD *thd __attribute__((__unused__)),
 
1717
                             struct st_mysql_sys_var *var __attribute__((__unused__)),
1541
1718
                             void *tgt, const void *save)
1542
1719
{
1543
 
  *(bool *) tgt= *(int *) save ? 1 : 0;
 
1720
  *(my_bool *) tgt= *(int *) save ? 1 : 0;
1544
1721
}
1545
1722
 
1546
1723
 
1547
 
static void update_func_int(THD *thd __attribute__((unused)),
1548
 
                            struct st_mysql_sys_var *var __attribute__((unused)),
 
1724
static void update_func_int(THD *thd __attribute__((__unused__)),
 
1725
                            struct st_mysql_sys_var *var __attribute__((__unused__)),
1549
1726
                             void *tgt, const void *save)
1550
1727
{
1551
1728
  *(int *)tgt= *(int *) save;
1552
1729
}
1553
1730
 
1554
1731
 
1555
 
static void update_func_long(THD *thd __attribute__((unused)),
1556
 
                             struct st_mysql_sys_var *var __attribute__((unused)),
 
1732
static void update_func_long(THD *thd __attribute__((__unused__)),
 
1733
                             struct st_mysql_sys_var *var __attribute__((__unused__)),
1557
1734
                             void *tgt, const void *save)
1558
1735
{
1559
1736
  *(long *)tgt= *(long *) save;
1560
1737
}
1561
1738
 
1562
1739
 
1563
 
static void update_func_int64_t(THD *thd __attribute__((unused)),
1564
 
                                 struct st_mysql_sys_var *var __attribute__((unused)),
 
1740
static void update_func_longlong(THD *thd __attribute__((__unused__)),
 
1741
                                 struct st_mysql_sys_var *var __attribute__((__unused__)),
1565
1742
                                 void *tgt, const void *save)
1566
1743
{
1567
 
  *(int64_t *)tgt= *(uint64_t *) save;
 
1744
  *(longlong *)tgt= *(ulonglong *) save;
1568
1745
}
1569
1746
 
1570
1747
 
1571
 
static void update_func_str(THD *thd __attribute__((unused)), struct st_mysql_sys_var *var,
 
1748
static void update_func_str(THD *thd __attribute__((__unused__)), struct st_mysql_sys_var *var,
1572
1749
                             void *tgt, const void *save)
1573
1750
{
1574
1751
  char *old= *(char **) tgt;
1576
1753
  if (var->flags & PLUGIN_VAR_MEMALLOC)
1577
1754
  {
1578
1755
    *(char **)tgt= my_strdup(*(char **) save, MYF(0));
1579
 
    free(old);
 
1756
    my_free(old, MYF(0));
1580
1757
  }
1581
1758
}
1582
1759
 
1586
1763
****************************************************************************/
1587
1764
 
1588
1765
 
1589
 
sys_var *find_sys_var(THD *thd, const char *str, uint32_t length)
 
1766
sys_var *find_sys_var(THD *thd, const char *str, uint length)
1590
1767
{
1591
1768
  sys_var *var;
1592
1769
  sys_var_pluginvar *pi= NULL;
1626
1803
  Returns the 'bookmark' for the named variable.
1627
1804
  LOCK_system_variables_hash should be at least read locked
1628
1805
*/
1629
 
static st_bookmark *find_bookmark(const char *plugin, const char *name, int flags)
 
1806
static st_bookmark *find_bookmark(const char *plugin, const char *name,
 
1807
                                  int flags)
1630
1808
{
1631
1809
  st_bookmark *result= NULL;
1632
 
  uint32_t namelen, length, pluginlen= 0;
 
1810
  uint namelen, length, pluginlen= 0;
1633
1811
  char *varname, *p;
1634
1812
 
1635
1813
  if (!(flags & PLUGIN_VAR_THDLOCAL))
1643
1821
 
1644
1822
  if (plugin)
1645
1823
  {
1646
 
    strxmov(varname + 1, plugin, "_", name, NULL);
 
1824
    strxmov(varname + 1, plugin, "_", name, NullS);
1647
1825
    for (p= varname + 1; *p; p++)
1648
1826
      if (*p == '-')
1649
1827
        *p= '_';
1654
1832
  varname[0]= flags & PLUGIN_VAR_TYPEMASK;
1655
1833
 
1656
1834
  result= (st_bookmark*) hash_search(&bookmark_hash,
1657
 
                                     (const unsigned char*) varname, length - 1);
 
1835
                                     (const uchar*) varname, length - 1);
1658
1836
 
1659
1837
  my_afree(varname);
1660
1838
  return result;
1669
1847
static st_bookmark *register_var(const char *plugin, const char *name,
1670
1848
                                 int flags)
1671
1849
{
1672
 
  uint32_t length= strlen(plugin) + strlen(name) + 3, size= 0, offset, new_size;
 
1850
  uint length= strlen(plugin) + strlen(name) + 3, size= 0, offset, new_size;
1673
1851
  st_bookmark *result;
1674
1852
  char *varname, *p;
1675
1853
 
1678
1856
 
1679
1857
  switch (flags & PLUGIN_VAR_TYPEMASK) {
1680
1858
  case PLUGIN_VAR_BOOL:
1681
 
    size= sizeof(bool);
 
1859
    size= sizeof(my_bool);
1682
1860
    break;
1683
1861
  case PLUGIN_VAR_INT:
1684
1862
    size= sizeof(int);
1689
1867
    break;
1690
1868
  case PLUGIN_VAR_LONGLONG:
1691
1869
  case PLUGIN_VAR_SET:
1692
 
    size= sizeof(uint64_t);
 
1870
    size= sizeof(ulonglong);
1693
1871
    break;
1694
1872
  case PLUGIN_VAR_STR:
1695
1873
    size= sizeof(char*);
1700
1878
  };
1701
1879
 
1702
1880
  varname= ((char*) my_alloca(length));
1703
 
  strxmov(varname + 1, plugin, "_", name, NULL);
 
1881
  strxmov(varname + 1, plugin, "_", name, NullS);
1704
1882
  for (p= varname + 1; *p; p++)
1705
1883
    if (*p == '-')
1706
1884
      *p= '_';
1735
1913
        variables. If their value is non-NULL, it must point to a valid
1736
1914
        string.
1737
1915
      */
1738
 
      memset(global_system_variables.dynamic_variables_ptr +
1739
 
             global_variables_dynamic_size, 0,
1740
 
             new_size - global_variables_dynamic_size);
1741
 
      memset(max_system_variables.dynamic_variables_ptr +
1742
 
             global_variables_dynamic_size, 0, 
1743
 
             new_size - global_variables_dynamic_size);
 
1916
      bzero(global_system_variables.dynamic_variables_ptr +
 
1917
            global_variables_dynamic_size,
 
1918
            new_size - global_variables_dynamic_size);
 
1919
      bzero(max_system_variables.dynamic_variables_ptr +
 
1920
            global_variables_dynamic_size,
 
1921
            new_size - global_variables_dynamic_size);
1744
1922
      global_variables_dynamic_size= new_size;
1745
1923
    }
1746
1924
 
1754
1932
    result->version= global_system_variables.dynamic_variables_version;
1755
1933
 
1756
1934
    /* this should succeed because we have already checked if a dup exists */
1757
 
    if (my_hash_insert(&bookmark_hash, (unsigned char*) result))
 
1935
    if (my_hash_insert(&bookmark_hash, (uchar*) result))
1758
1936
    {
1759
1937
      fprintf(stderr, "failed to add placeholder to hash");
1760
1938
      assert(0);
1771
1949
  If required, will sync with global variables if the requested variable
1772
1950
  has not yet been allocated in the current thread.
1773
1951
*/
1774
 
static unsigned char *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
 
1952
static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
1775
1953
{
1776
1954
  assert(offset >= 0);
1777
1955
  assert((uint)offset <= global_system_variables.dynamic_variables_head);
1778
1956
 
1779
1957
  if (!thd)
1780
 
    return (unsigned char*) global_system_variables.dynamic_variables_ptr + offset;
 
1958
    return (uchar*) global_system_variables.dynamic_variables_ptr + offset;
1781
1959
 
1782
1960
  /*
1783
1961
    dynamic_variables_head points to the largest valid offset
1785
1963
  if (!thd->variables.dynamic_variables_ptr ||
1786
1964
      (uint)offset > thd->variables.dynamic_variables_head)
1787
1965
  {
1788
 
    uint32_t idx;
 
1966
    uint idx;
1789
1967
 
1790
1968
    rw_rdlock(&LOCK_system_variables_hash);
1791
1969
 
1847
2025
 
1848
2026
    rw_unlock(&LOCK_system_variables_hash);
1849
2027
  }
1850
 
  return (unsigned char*)thd->variables.dynamic_variables_ptr + offset;
1851
 
}
1852
 
 
1853
 
static bool *mysql_sys_var_ptr_bool(THD* a_thd, int offset)
1854
 
{
1855
 
  return (bool *)intern_sys_var_ptr(a_thd, offset, true);
1856
 
}
1857
 
 
1858
 
static int *mysql_sys_var_ptr_int(THD* a_thd, int offset)
1859
 
{
1860
 
  return (int *)intern_sys_var_ptr(a_thd, offset, true);
1861
 
}
1862
 
 
1863
 
static long *mysql_sys_var_ptr_long(THD* a_thd, int offset)
1864
 
{
1865
 
  return (long *)intern_sys_var_ptr(a_thd, offset, true);
1866
 
}
1867
 
 
1868
 
static int64_t *mysql_sys_var_ptr_int64_t(THD* a_thd, int offset)
1869
 
{
1870
 
  return (int64_t *)intern_sys_var_ptr(a_thd, offset, true);
1871
 
}
1872
 
 
1873
 
static char **mysql_sys_var_ptr_str(THD* a_thd, int offset)
1874
 
{
1875
 
  return (char **)intern_sys_var_ptr(a_thd, offset, true);
1876
 
}
1877
 
 
1878
 
static uint64_t *mysql_sys_var_ptr_set(THD* a_thd, int offset)
1879
 
{
1880
 
  return (uint64_t *)intern_sys_var_ptr(a_thd, offset, true);
1881
 
}
1882
 
 
1883
 
static unsigned long *mysql_sys_var_ptr_enum(THD* a_thd, int offset)
1884
 
{
1885
 
  return (unsigned long *)intern_sys_var_ptr(a_thd, offset, true);
 
2028
  return (uchar*)thd->variables.dynamic_variables_ptr + offset;
 
2029
}
 
2030
 
 
2031
static uchar *mysql_sys_var_ptr(void* a_thd, int offset)
 
2032
{
 
2033
  return intern_sys_var_ptr((THD *)a_thd, offset, true);
1886
2034
}
1887
2035
 
1888
2036
 
1911
2059
/*
1912
2060
  Unlocks all system variables which hold a reference
1913
2061
*/
1914
 
static void unlock_variables(THD *thd __attribute__((unused)),
 
2062
static void unlock_variables(THD *thd __attribute__((__unused__)),
1915
2063
                             struct system_variables *vars)
1916
2064
{
1917
2065
  intern_plugin_unlock(NULL, vars->table_plugin);
1931
2079
  sys_var_pluginvar *pivar;
1932
2080
  sys_var *var;
1933
2081
  int flags;
1934
 
  uint32_t idx;
 
2082
  uint idx;
1935
2083
 
1936
2084
  rw_rdlock(&LOCK_system_variables_hash);
1937
2085
  for (idx= 0; idx < bookmark_hash.records; idx++)
1949
2097
        flags & PLUGIN_VAR_THDLOCAL && flags & PLUGIN_VAR_MEMALLOC)
1950
2098
    {
1951
2099
      char **ptr= (char**) pivar->real_value_ptr(thd, OPT_SESSION);
1952
 
      free(*ptr);
 
2100
      my_free(*ptr, MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
1953
2101
      *ptr= NULL;
1954
2102
    }
1955
2103
  }
1957
2105
 
1958
2106
  assert(vars->table_plugin == NULL);
1959
2107
 
1960
 
  free(vars->dynamic_variables_ptr);
 
2108
  my_free(vars->dynamic_variables_ptr, MYF(MY_ALLOW_ZERO_PTR));
1961
2109
  vars->dynamic_variables_ptr= NULL;
1962
2110
  vars->dynamic_variables_size= 0;
1963
2111
  vars->dynamic_variables_version= 0;
1966
2114
 
1967
2115
void plugin_thdvar_cleanup(THD *thd)
1968
2116
{
1969
 
  uint32_t idx;
 
2117
  uint idx;
1970
2118
  plugin_ref *list;
1971
2119
 
1972
2120
  unlock_variables(thd, &thd->variables);
1975
2123
  if ((idx= thd->lex->plugins.elements))
1976
2124
  {
1977
2125
    list= ((plugin_ref*) thd->lex->plugins.buffer) + idx - 1;
1978
 
    while ((unsigned char*) list >= thd->lex->plugins.buffer)
 
2126
    while ((uchar*) list >= thd->lex->plugins.buffer)
1979
2127
      intern_plugin_unlock(NULL, *list--);
1980
2128
  }
1981
2129
 
 
2130
  reap_plugins();
 
2131
 
1982
2132
  reset_dynamic(&thd->lex->plugins);
1983
2133
 
1984
2134
  return;
2008
2158
    {
2009
2159
      /* Free the string from global_system_variables. */
2010
2160
      char **valptr= (char**) piv->real_value_ptr(NULL, OPT_GLOBAL);
2011
 
      free(*valptr);
 
2161
      my_free(*valptr, MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
2012
2162
      *valptr= NULL;
2013
2163
    }
2014
2164
  }
2056
2206
}
2057
2207
 
2058
2208
 
2059
 
unsigned char* sys_var_pluginvar::real_value_ptr(THD *thd, enum_var_type type)
 
2209
uchar* sys_var_pluginvar::real_value_ptr(THD *thd, enum_var_type type)
2060
2210
{
2061
2211
  assert(thd || (type == OPT_GLOBAL));
2062
2212
  if (plugin_var->flags & PLUGIN_VAR_THDLOCAL)
2066
2216
 
2067
2217
    return intern_sys_var_ptr(thd, *(int*) (plugin_var+1), false);
2068
2218
  }
2069
 
  return *(unsigned char**) (plugin_var+1);
 
2219
  return *(uchar**) (plugin_var+1);
2070
2220
}
2071
2221
 
2072
2222
 
2088
2238
}
2089
2239
 
2090
2240
 
2091
 
unsigned char* sys_var_pluginvar::value_ptr(THD *thd, enum_var_type type,
2092
 
                                    LEX_STRING *base __attribute__((unused)))
 
2241
uchar* sys_var_pluginvar::value_ptr(THD *thd, enum_var_type type,
 
2242
                                    LEX_STRING *base __attribute__((__unused__)))
2093
2243
{
2094
 
  unsigned char* result;
 
2244
  uchar* result;
2095
2245
 
2096
2246
  result= real_value_ptr(thd, type);
2097
2247
 
2098
2248
  if ((plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_ENUM)
2099
 
    result= (unsigned char*) get_type(plugin_var_typelib(), *(ulong*)result);
 
2249
    result= (uchar*) get_type(plugin_var_typelib(), *(ulong*)result);
2100
2250
  else if ((plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_SET)
2101
2251
  {
2102
2252
    char buffer[STRING_BUFFER_USUAL_SIZE];
2103
2253
    String str(buffer, sizeof(buffer), system_charset_info);
2104
2254
    TYPELIB *typelib= plugin_var_typelib();
2105
 
    uint64_t mask= 1, value= *(uint64_t*) result;
2106
 
    uint32_t i;
 
2255
    ulonglong mask= 1, value= *(ulonglong*) result;
 
2256
    uint i;
2107
2257
 
2108
2258
    str.length(0);
2109
2259
    for (i= 0; i < typelib->count; i++, mask<<=1)
2114
2264
      str.append(',');
2115
2265
    }
2116
2266
 
2117
 
    result= (unsigned char*) "";
 
2267
    result= (uchar*) "";
2118
2268
    if (str.length())
2119
 
      result= (unsigned char*) thd->strmake(str.ptr(), str.length()-1);
 
2269
      result= (uchar*) thd->strmake(str.ptr(), str.length()-1);
2120
2270
  }
2121
2271
  return result;
2122
2272
}
2165
2315
          src= &((thdvar_ulong_t*) plugin_var)->def_val;
2166
2316
          break;
2167
2317
        case PLUGIN_VAR_LONGLONG:
2168
 
          src= &((thdvar_uint64_t_t*) plugin_var)->def_val;
 
2318
          src= &((thdvar_ulonglong_t*) plugin_var)->def_val;
2169
2319
          break;
2170
2320
        case PLUGIN_VAR_ENUM:
2171
2321
          src= &((thdvar_enum_t*) plugin_var)->def_val;
2233
2383
 
2234
2384
 
2235
2385
#define OPTION_SET_LIMITS(type, options, opt) \
2236
 
  options->var_type= type;                    \
2237
 
  options->def_value= (opt)->def_val;         \
2238
 
  options->min_value= (opt)->min_val;         \
2239
 
  options->max_value= (opt)->max_val;         \
 
2386
  options->var_type= type; \
 
2387
  options->def_value= (opt)->def_val; \
 
2388
  options->min_value= (opt)->min_val; \
 
2389
  options->max_value= (opt)->max_val; \
2240
2390
  options->block_size= (long) (opt)->blk_sz
2241
2391
 
2242
2392
 
2261
2411
    OPTION_SET_LIMITS(GET_ULONG, options, (sysvar_ulong_t*) opt);
2262
2412
    break;
2263
2413
  case PLUGIN_VAR_LONGLONG:
2264
 
    OPTION_SET_LIMITS(GET_LL, options, (sysvar_int64_t_t*) opt);
 
2414
    OPTION_SET_LIMITS(GET_LL, options, (sysvar_longlong_t*) opt);
2265
2415
    break;
2266
2416
  case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED:
2267
 
    OPTION_SET_LIMITS(GET_ULL, options, (sysvar_uint64_t_t*) opt);
 
2417
    OPTION_SET_LIMITS(GET_ULL, options, (sysvar_ulonglong_t*) opt);
2268
2418
    break;
2269
2419
  case PLUGIN_VAR_ENUM:
2270
2420
    options->var_type= GET_ENUM;
2278
2428
    options->typelib= ((sysvar_set_t*) opt)->typelib;
2279
2429
    options->def_value= ((sysvar_set_t*) opt)->def_val;
2280
2430
    options->min_value= options->block_size= 0;
2281
 
    options->max_value= (1UL << options->typelib->count) - 1;
 
2431
    options->max_value= (1ULL << options->typelib->count) - 1;
2282
2432
    break;
2283
2433
  case PLUGIN_VAR_BOOL:
2284
2434
    options->var_type= GET_BOOL;
2287
2437
  case PLUGIN_VAR_STR:
2288
2438
    options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ?
2289
2439
                        GET_STR_ALLOC : GET_STR);
2290
 
    options->def_value= (intptr_t) ((sysvar_str_t*) opt)->def_val;
 
2440
    options->def_value= (intptr) ((sysvar_str_t*) opt)->def_val;
2291
2441
    break;
2292
2442
  /* threadlocal variables */
2293
2443
  case PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL:
2303
2453
    OPTION_SET_LIMITS(GET_ULONG, options, (thdvar_ulong_t*) opt);
2304
2454
    break;
2305
2455
  case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_THDLOCAL:
2306
 
    OPTION_SET_LIMITS(GET_LL, options, (thdvar_int64_t_t*) opt);
 
2456
    OPTION_SET_LIMITS(GET_LL, options, (thdvar_longlong_t*) opt);
2307
2457
    break;
2308
2458
  case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_THDLOCAL:
2309
 
    OPTION_SET_LIMITS(GET_ULL, options, (thdvar_uint64_t_t*) opt);
 
2459
    OPTION_SET_LIMITS(GET_ULL, options, (thdvar_ulonglong_t*) opt);
2310
2460
    break;
2311
2461
  case PLUGIN_VAR_ENUM | PLUGIN_VAR_THDLOCAL:
2312
2462
    options->var_type= GET_ENUM;
2320
2470
    options->typelib= ((thdvar_set_t*) opt)->typelib;
2321
2471
    options->def_value= ((thdvar_set_t*) opt)->def_val;
2322
2472
    options->min_value= options->block_size= 0;
2323
 
    options->max_value= (1UL << options->typelib->count) - 1;
 
2473
    options->max_value= (1ULL << options->typelib->count) - 1;
2324
2474
    break;
2325
2475
  case PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL:
2326
2476
    options->var_type= GET_BOOL;
2329
2479
  case PLUGIN_VAR_STR | PLUGIN_VAR_THDLOCAL:
2330
2480
    options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ?
2331
2481
                        GET_STR_ALLOC : GET_STR);
2332
 
    options->def_value= (intptr_t) ((thdvar_str_t*) opt)->def_val;
 
2482
    options->def_value= (intptr) ((thdvar_str_t*) opt)->def_val;
2333
2483
    break;
2334
2484
  default:
2335
2485
    assert(0);
2341
2491
    options->arg_type= OPT_ARG;
2342
2492
}
2343
2493
 
2344
 
extern "C" bool get_one_plugin_option(int optid, const struct my_option *,
 
2494
extern "C" my_bool get_one_plugin_option(int optid, const struct my_option *,
2345
2495
                                         char *);
2346
2496
 
2347
 
bool get_one_plugin_option(int optid __attribute__((unused)),
2348
 
                              const struct my_option *opt __attribute__((unused)),
2349
 
                              char *argument __attribute__((unused)))
 
2497
my_bool get_one_plugin_option(int optid __attribute__((unused)),
 
2498
                              const struct my_option *opt __attribute__((__unused__)),
 
2499
                              char *argument __attribute__((__unused__)))
2350
2500
{
2351
2501
  return 0;
2352
2502
}
2353
2503
 
2354
2504
 
2355
2505
static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
2356
 
                             my_option *options, bool can_disable)
 
2506
                             my_option *options, my_bool **enabled,
 
2507
                             bool can_disable)
2357
2508
{
2358
2509
  const char *plugin_name= tmp->plugin->name;
2359
 
  uint32_t namelen= strlen(plugin_name), optnamelen;
2360
 
  uint32_t buffer_length= namelen * 4 + (can_disable ? 75 : 10);
 
2510
  uint namelen= strlen(plugin_name), optnamelen;
 
2511
  uint buffer_length= namelen * 4 + (can_disable ? 75 : 10);
2361
2512
  char *name= (char*) alloc_root(mem_root, buffer_length) + 1;
2362
2513
  char *optname, *p;
2363
2514
  int index= 0, offset= 0;
2366
2517
 
2367
2518
  /* support --skip-plugin-foo syntax */
2368
2519
  memcpy(name, plugin_name, namelen + 1);
2369
 
  my_casedn_str(&my_charset_utf8_general_ci, name);
2370
 
  strxmov(name + namelen + 1, "plugin-", name, NULL);
 
2520
  my_casedn_str(&my_charset_latin1, name);
 
2521
  strxmov(name + namelen + 1, "plugin-", name, NullS);
2371
2522
  /* Now we have namelen + 1 + 7 + namelen + 1 == namelen * 2 + 9. */
2372
2523
 
2373
2524
  for (p= name + namelen*2 + 8; p > name; p--)
2377
2528
  if (can_disable)
2378
2529
  {
2379
2530
    strxmov(name + namelen*2 + 10, "Enable ", plugin_name, " plugin. "
2380
 
            "Disable with --skip-", name," (will save memory).", NULL);
 
2531
            "Disable with --skip-", name," (will save memory).", NullS);
2381
2532
    /*
2382
2533
      Now we have namelen * 2 + 10 (one char unused) + 7 + namelen + 9 +
2383
2534
      20 + namelen + 20 + 1 == namelen * 4 + 67.
2386
2537
    options[0].comment= name + namelen*2 + 10;
2387
2538
  }
2388
2539
 
 
2540
  /*
 
2541
    NOTE: 'name' is one char above the allocated buffer!
 
2542
    NOTE: This code assumes that 'my_bool' and 'char' are of same size.
 
2543
  */
 
2544
  *((my_bool *)(name -1))= **enabled;
 
2545
  *enabled= (my_bool *)(name - 1);
 
2546
 
 
2547
 
2389
2548
  options[1].name= (options[0].name= name) + namelen + 1;
2390
2549
  options[0].id= options[1].id= 256; /* must be >255. dup id ok */
2391
2550
  options[0].var_type= options[1].var_type= GET_BOOL;
2392
2551
  options[0].arg_type= options[1].arg_type= NO_ARG;
2393
 
  options[0].def_value= options[1].def_value= true;
 
2552
  options[0].def_value= options[1].def_value= **enabled;
2394
2553
  options[0].value= options[0].u_max_value=
2395
2554
  options[1].value= options[1].u_max_value= (char**) (name - 1);
2396
2555
  options+= 2;
2410
2569
      continue;
2411
2570
    switch (opt->flags & PLUGIN_VAR_TYPEMASK) {
2412
2571
    case PLUGIN_VAR_BOOL:
2413
 
      (((thdvar_bool_t *)opt)->resolve)= mysql_sys_var_ptr_bool;
 
2572
      SET_PLUGIN_VAR_RESOLVE((thdvar_bool_t *) opt);
2414
2573
      break;
2415
2574
    case PLUGIN_VAR_INT:
2416
 
      (((thdvar_int_t *)opt)->resolve)= mysql_sys_var_ptr_int;
 
2575
      SET_PLUGIN_VAR_RESOLVE((thdvar_int_t *) opt);
2417
2576
      break;
2418
2577
    case PLUGIN_VAR_LONG:
2419
 
      (((thdvar_long_t *)opt)->resolve)= mysql_sys_var_ptr_long;
 
2578
      SET_PLUGIN_VAR_RESOLVE((thdvar_long_t *) opt);
2420
2579
      break;
2421
2580
    case PLUGIN_VAR_LONGLONG:
2422
 
      (((thdvar_int64_t_t *)opt)->resolve)= mysql_sys_var_ptr_int64_t;
 
2581
      SET_PLUGIN_VAR_RESOLVE((thdvar_longlong_t *) opt);
2423
2582
      break;
2424
2583
    case PLUGIN_VAR_STR:
2425
 
      (((thdvar_str_t *)opt)->resolve)= mysql_sys_var_ptr_str;
 
2584
      SET_PLUGIN_VAR_RESOLVE((thdvar_str_t *) opt);
2426
2585
      break;
2427
2586
    case PLUGIN_VAR_ENUM:
2428
 
      (((thdvar_enum_t *)opt)->resolve)= mysql_sys_var_ptr_enum;
 
2587
      SET_PLUGIN_VAR_RESOLVE((thdvar_enum_t *) opt);
2429
2588
      break;
2430
2589
    case PLUGIN_VAR_SET:
2431
 
      (((thdvar_set_t *)opt)->resolve)= mysql_sys_var_ptr_set;
 
2590
      SET_PLUGIN_VAR_RESOLVE((thdvar_set_t *) opt);
2432
2591
      break;
2433
2592
    default:
2434
 
      sql_print_error(_("Unknown variable type code 0x%x in plugin '%s'."),
 
2593
      sql_print_error("Unknown variable type code 0x%x in plugin '%s'.",
2435
2594
                      opt->flags, plugin_name);
2436
2595
      return(-1);
2437
2596
    };
2461
2620
      break;
2462
2621
    case PLUGIN_VAR_LONGLONG:
2463
2622
      if (!opt->check)
2464
 
        opt->check= check_func_int64_t;
 
2623
        opt->check= check_func_longlong;
2465
2624
      if (!opt->update)
2466
 
        opt->update= update_func_int64_t;
 
2625
        opt->update= update_func_longlong;
2467
2626
      break;
2468
2627
    case PLUGIN_VAR_STR:
2469
2628
      if (!opt->check)
2474
2633
        if ((opt->flags & (PLUGIN_VAR_MEMALLOC | PLUGIN_VAR_READONLY)) == false)
2475
2634
        {
2476
2635
          opt->flags|= PLUGIN_VAR_READONLY;
2477
 
          sql_print_warning(_("Server variable %s of plugin %s was forced "
 
2636
          sql_print_warning("Server variable %s of plugin %s was forced "
2478
2637
                            "to be read-only: string variable without "
2479
 
                            "update_func and PLUGIN_VAR_MEMALLOC flag"),
 
2638
                            "update_func and PLUGIN_VAR_MEMALLOC flag",
2480
2639
                            opt->name, plugin_name);
2481
2640
        }
2482
2641
      }
2491
2650
      if (!opt->check)
2492
2651
        opt->check= check_func_set;
2493
2652
      if (!opt->update)
2494
 
        opt->update= update_func_int64_t;
 
2653
        opt->update= update_func_longlong;
2495
2654
      break;
2496
2655
    default:
2497
 
      sql_print_error(_("Unknown variable type code 0x%x in plugin '%s'."),
 
2656
      sql_print_error("Unknown variable type code 0x%x in plugin '%s'.",
2498
2657
                      opt->flags, plugin_name);
2499
2658
      return(-1);
2500
2659
    }
2505
2664
 
2506
2665
    if (!opt->name)
2507
2666
    {
2508
 
      sql_print_error(_("Missing variable name in plugin '%s'."),
 
2667
      sql_print_error("Missing variable name in plugin '%s'.",
2509
2668
                      plugin_name);
2510
2669
      return(-1);
2511
2670
    }
2514
2673
    {
2515
2674
      optnamelen= strlen(opt->name);
2516
2675
      optname= (char*) alloc_root(mem_root, namelen + optnamelen + 2);
2517
 
      strxmov(optname, name, "-", opt->name, NULL);
 
2676
      strxmov(optname, name, "-", opt->name, NullS);
2518
2677
      optnamelen= namelen + optnamelen + 1;
2519
2678
    }
2520
2679
    else
2522
2681
      /* this should not fail because register_var should create entry */
2523
2682
      if (!(v= find_bookmark(name, opt->name, opt->flags)))
2524
2683
      {
2525
 
        sql_print_error(_("Thread local variable '%s' not allocated "
2526
 
                        "in plugin '%s'."), opt->name, plugin_name);
 
2684
        sql_print_error("Thread local variable '%s' not allocated "
 
2685
                        "in plugin '%s'.", opt->name, plugin_name);
2527
2686
        return(-1);
2528
2687
      }
2529
2688
 
2557
2716
    options[1]= options[0];
2558
2717
    options[1].name= p= (char*) alloc_root(mem_root, optnamelen + 8);
2559
2718
    options[1].comment= 0; // hidden
2560
 
    strxmov(p, "plugin-", optname, NULL);
 
2719
    strxmov(p, "plugin-", optname, NullS);
2561
2720
 
2562
2721
    options+= 2;
2563
2722
  }
2571
2730
{
2572
2731
  st_mysql_sys_var **opt;
2573
2732
  my_option *opts;
2574
 
  bool can_disable;
2575
 
  uint32_t count= EXTRA_OPTIONS;
 
2733
  my_bool dummy, can_disable;
 
2734
  my_bool *dummy2= &dummy;
 
2735
  uint count= EXTRA_OPTIONS;
2576
2736
 
2577
2737
  for (opt= p->plugin->system_vars; opt && *opt; opt++, count+= 2) {};
2578
2738
 
2579
2739
  if (!(opts= (my_option*) alloc_root(mem_root, sizeof(my_option) * count)))
2580
2740
    return(NULL);
2581
2741
 
2582
 
  memset(opts, 0, sizeof(my_option) * count);
2583
 
 
2584
 
  if ((my_strcasecmp(&my_charset_utf8_general_ci, p->name.str, "MyISAM") == 0))
2585
 
    can_disable= false;
2586
 
  else if ((my_strcasecmp(&my_charset_utf8_general_ci, p->name.str, "MEMORY") == 0))
2587
 
    can_disable= false;
2588
 
  else
2589
 
    can_disable= true;
2590
 
 
2591
 
 
2592
 
  if (construct_options(mem_root, p, opts, can_disable))
 
2742
  bzero(opts, sizeof(my_option) * count);
 
2743
 
 
2744
  dummy= TRUE; /* plugin is enabled. */
 
2745
 
 
2746
  can_disable=
 
2747
      my_strcasecmp(&my_charset_latin1, p->name.str, "MyISAM") &&
 
2748
      my_strcasecmp(&my_charset_latin1, p->name.str, "MEMORY");
 
2749
 
 
2750
  if (construct_options(mem_root, p, opts, &dummy2, can_disable))
2593
2751
    return(NULL);
2594
2752
 
2595
2753
  return(opts);
2610
2768
    Requires that a write-lock is held on LOCK_system_variables_hash
2611
2769
*/
2612
2770
static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
2613
 
                               int *argc, char **argv)
 
2771
                               int *argc, char **argv, my_bool default_enabled)
2614
2772
{
2615
2773
  struct sys_var_chain chain= { NULL, NULL };
2616
 
  bool enabled_saved= true;
2617
 
  bool can_disable;
 
2774
  my_bool enabled_saved= default_enabled, can_disable;
 
2775
  my_bool *enabled= &default_enabled;
2618
2776
  MEM_ROOT *mem_root= alloc_root_inited(&tmp->mem_root) ?
2619
2777
                      &tmp->mem_root : &plugin_mem_root;
2620
2778
  st_mysql_sys_var **opt;
2624
2782
  st_mysql_sys_var *o;
2625
2783
  sys_var *v;
2626
2784
  struct st_bookmark *var;
2627
 
  uint32_t len, count= EXTRA_OPTIONS;
 
2785
  uint len, count= EXTRA_OPTIONS;
2628
2786
  assert(tmp->plugin && tmp->name.str);
2629
2787
 
2630
2788
  for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
2631
2789
    count+= 2; /* --{plugin}-{optname} and --plugin-{plugin}-{optname} */
2632
2790
 
2633
 
  if ((my_strcasecmp(&my_charset_utf8_general_ci, tmp->name.str, "MyISAM") == 0))
2634
 
    can_disable= false;
2635
 
  else if ((my_strcasecmp(&my_charset_utf8_general_ci, tmp->name.str, "MEMORY") == 0))
2636
 
    can_disable= false;
2637
 
  else
2638
 
    can_disable= true;
 
2791
  can_disable=
 
2792
      my_strcasecmp(&my_charset_latin1, tmp->name.str, "MyISAM") &&
 
2793
      my_strcasecmp(&my_charset_latin1, tmp->name.str, "MEMORY");
2639
2794
 
2640
2795
  if (count > EXTRA_OPTIONS || (*argc > 1))
2641
2796
  {
2642
2797
    if (!(opts= (my_option*) alloc_root(tmp_root, sizeof(my_option) * count)))
2643
2798
    {
2644
 
      sql_print_error(_("Out of memory for plugin '%s'."), tmp->name.str);
 
2799
      sql_print_error("Out of memory for plugin '%s'.", tmp->name.str);
2645
2800
      return(-1);
2646
2801
    }
2647
 
    memset(opts, 0, sizeof(my_option) * count);
 
2802
    bzero(opts, sizeof(my_option) * count);
2648
2803
 
2649
 
    if (construct_options(tmp_root, tmp, opts, can_disable))
 
2804
    if (construct_options(tmp_root, tmp, opts, &enabled, can_disable))
2650
2805
    {
2651
 
      sql_print_error(_("Bad options for plugin '%s'."), tmp->name.str);
 
2806
      sql_print_error("Bad options for plugin '%s'.", tmp->name.str);
2652
2807
      return(-1);
2653
2808
    }
2654
2809
 
2657
2812
 
2658
2813
    if (error)
2659
2814
    {
2660
 
       sql_print_error(_("Parsing options for plugin '%s' failed."),
 
2815
       sql_print_error("Parsing options for plugin '%s' failed.",
2661
2816
                       tmp->name.str);
2662
2817
       goto err;
2663
2818
    }
2664
2819
  }
2665
2820
 
 
2821
  if (!*enabled && !can_disable)
 
2822
  {
 
2823
    sql_print_warning("Plugin '%s' cannot be disabled", tmp->name.str);
 
2824
    *enabled= TRUE;
 
2825
  }
 
2826
 
2666
2827
  error= 1;
2667
2828
 
 
2829
  if (*enabled)
2668
2830
  {
2669
2831
    for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
2670
2832
    {
2677
2839
      {
2678
2840
        len= tmp->name.length + strlen(o->name) + 2;
2679
2841
        varname= (char*) alloc_root(mem_root, len);
2680
 
        strxmov(varname, tmp->name.str, "-", o->name, NULL);
2681
 
        my_casedn_str(&my_charset_utf8_general_ci, varname);
 
2842
        strxmov(varname, tmp->name.str, "-", o->name, NullS);
 
2843
        my_casedn_str(&my_charset_latin1, varname);
2682
2844
 
2683
2845
        for (p= varname; *p; p++)
2684
2846
          if (*p == '-')
2700
2862
      chain.last->next = NULL;
2701
2863
      if (mysql_add_sys_var_chain(chain.first, NULL))
2702
2864
      {
2703
 
        sql_print_error(_("Plugin '%s' has conflicting system variables"),
 
2865
        sql_print_error("Plugin '%s' has conflicting system variables",
2704
2866
                        tmp->name.str);
2705
2867
        goto err;
2706
2868
      }
2710
2872
  }
2711
2873
 
2712
2874
  if (enabled_saved && global_system_variables.log_warnings)
2713
 
    sql_print_information(_("Plugin '%s' disabled by command line option"),
 
2875
    sql_print_information("Plugin '%s' disabled by command line option",
2714
2876
                          tmp->name.str);
2715
2877
err:
2716
2878
  if (opts)
2725
2887
 
2726
2888
static int option_cmp(my_option *a, my_option *b)
2727
2889
{
2728
 
  return my_strcasecmp(&my_charset_utf8_general_ci, a->name, b->name);
 
2890
  return my_strcasecmp(&my_charset_latin1, a->name, b->name);
2729
2891
}
2730
2892
 
2731
2893
 
2732
 
void my_print_help_inc_plugins(my_option *main_options, uint32_t size)
 
2894
void my_print_help_inc_plugins(my_option *main_options, uint size)
2733
2895
{
2734
2896
  DYNAMIC_ARRAY all_options;
2735
2897
  struct st_plugin_int *p;
2740
2902
  my_init_dynamic_array(&all_options, sizeof(my_option), size, size/4);
2741
2903
 
2742
2904
  if (initialized)
2743
 
    for (uint32_t idx= 0; idx < plugin_array.elements; idx++)
 
2905
    for (uint idx= 0; idx < plugin_array.elements; idx++)
2744
2906
    {
2745
2907
      p= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
2746
2908
 
2751
2913
      /* Only options with a non-NULL comment are displayed in help text */
2752
2914
      for (;opt->id; opt++)
2753
2915
        if (opt->comment)
2754
 
          insert_dynamic(&all_options, (unsigned char*) opt);
 
2916
          insert_dynamic(&all_options, (uchar*) opt);
2755
2917
    }
2756
2918
 
2757
2919
  for (;main_options->id; main_options++)
2758
 
    insert_dynamic(&all_options, (unsigned char*) main_options);
 
2920
    insert_dynamic(&all_options, (uchar*) main_options);
2759
2921
 
2760
2922
  sort_dynamic(&all_options, (qsort_cmp) option_cmp);
2761
2923
 
2762
2924
  /* main_options now points to the empty option terminator */
2763
 
  insert_dynamic(&all_options, (unsigned char*) main_options);
 
2925
  insert_dynamic(&all_options, (uchar*) main_options);
2764
2926
 
2765
2927
  my_print_help((my_option*) all_options.buffer);
2766
2928
  my_print_variables((my_option*) all_options.buffer);