~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2005 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
16
#include <drizzled/server_includes.h>
212.5.21 by Monty Taylor
Moved my_getopt.h
17
#include <mysys/my_getopt.h>
499.2.9 by Mark Atwood
fix mistakes
18
259 by Brian Aker
First pass on PAM auth
19
#include <authentication.h>
383.6.1 by Mark Atwood
add pluggable logging
20
#include <logging.h>
499.2.7 by Mark Atwood
some bugs in errmsg plugin
21
#include <errmsg.h>
499.2.9 by Mark Atwood
fix mistakes
22
#include <configvar.h>
23
#include <qcache.h>
24
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
25
#include <string>
26
202.3.6 by Monty Taylor
First pass at gettexizing the error messages.
27
#include <drizzled/drizzled_error_messages.h>
499.2.7 by Mark Atwood
some bugs in errmsg plugin
28
1 by brian
clean slate
29
#define REPORT_TO_LOG  1
30
#define REPORT_TO_USER 2
31
32
#define plugin_ref_to_int(A) (A ? A[0] : NULL)
33
#define plugin_int_to_ref(A) &(A)
34
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
35
using namespace std;
36
1 by brian
clean slate
37
extern struct st_mysql_plugin *mysqld_builtins[];
38
39
char *opt_plugin_load= NULL;
40
char *opt_plugin_dir_ptr;
41
char opt_plugin_dir[FN_REFLEN];
42
/*
43
  When you ad a new plugin type, add both a string and make sure that the
44
  init and deinit array are correctly updated.
45
*/
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
46
const LEX_STRING plugin_type_names[DRIZZLE_MAX_PLUGIN_TYPE_NUM]=
1 by brian
clean slate
47
{
190.1.1 by Mark Atwood
reorder plugin type numbering
48
  { C_STRING_WITH_LEN("DAEMON") },
49
  { C_STRING_WITH_LEN("STORAGE ENGINE") },
50
  { C_STRING_WITH_LEN("INFORMATION SCHEMA") },
1 by brian
clean slate
51
  { C_STRING_WITH_LEN("UDF") },
160.1.1 by mark
Stubs for plugin types for UDA, LOG, and AUTH
52
  { C_STRING_WITH_LEN("UDA") },
53
  { C_STRING_WITH_LEN("AUDIT") },
190.1.1 by Mark Atwood
reorder plugin type numbering
54
  { C_STRING_WITH_LEN("LOGGER") },
520.2.1 by Mark Atwood
define new plugin types, config and qcache
55
  { C_STRING_WITH_LEN("ERRMSG") },
56
  { C_STRING_WITH_LEN("AUTH") },
499.2.6 by Mark Atwood
an implemention of the errmsg plugin
57
  { C_STRING_WITH_LEN("CONFIGVAR") },
520.2.1 by Mark Atwood
define new plugin types, config and qcache
58
  { C_STRING_WITH_LEN("QCACHE") }
1 by brian
clean slate
59
};
60
61
extern int initialize_schema_table(st_plugin_int *plugin);
62
extern int finalize_schema_table(st_plugin_int *plugin);
63
134.1.1 by Mark Atwood
more hackery to get plugin UDFs working
64
extern int initialize_udf(st_plugin_int *plugin);
65
extern int finalize_udf(st_plugin_int *plugin);
66
1 by brian
clean slate
67
/*
68
  The number of elements in both plugin_type_initialize and
69
  plugin_type_deinitialize should equal to the number of plugins
70
  defined.
71
*/
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
72
plugin_type_init plugin_type_initialize[DRIZZLE_MAX_PLUGIN_TYPE_NUM]=
1 by brian
clean slate
73
{
190.1.1 by Mark Atwood
reorder plugin type numbering
74
  0,  /* Daemon */
160.1.1 by mark
Stubs for plugin types for UDA, LOG, and AUTH
75
  ha_initialize_handlerton,  /* Storage Engine */
76
  initialize_schema_table,  /* Information Schema */
190.1.1 by Mark Atwood
reorder plugin type numbering
77
  initialize_udf,  /* UDF */
78
  0,  /* UDA */
160.1.1 by mark
Stubs for plugin types for UDA, LOG, and AUTH
79
  0,  /* Audit */
383.6.1 by Mark Atwood
add pluggable logging
80
  logging_initializer,  /* Logger */
520.2.1 by Mark Atwood
define new plugin types, config and qcache
81
  errmsg_initializer,  /* Error Messages */
499.2.6 by Mark Atwood
an implemention of the errmsg plugin
82
  authentication_initializer,  /* Auth */
83
  configvar_initializer,
84
  qcache_initializer
1 by brian
clean slate
85
};
86
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
87
plugin_type_init plugin_type_deinitialize[DRIZZLE_MAX_PLUGIN_TYPE_NUM]=
1 by brian
clean slate
88
{
190.1.1 by Mark Atwood
reorder plugin type numbering
89
  0,  /* Daemon */
160.1.1 by mark
Stubs for plugin types for UDA, LOG, and AUTH
90
  ha_finalize_handlerton,  /* Storage Engine */
91
  finalize_schema_table,  /* Information Schema */
190.1.1 by Mark Atwood
reorder plugin type numbering
92
  finalize_udf,  /* UDF */
93
  0,  /* UDA */
160.1.1 by mark
Stubs for plugin types for UDA, LOG, and AUTH
94
  0,  /* Audit */
383.6.1 by Mark Atwood
add pluggable logging
95
  logging_finalizer,  /* Logger */
520.2.1 by Mark Atwood
define new plugin types, config and qcache
96
  errmsg_finalizer,  /* Logger */
499.2.6 by Mark Atwood
an implemention of the errmsg plugin
97
  authentication_finalizer,  /* Auth */
98
  configvar_finalizer,
99
  qcache_finalizer
1 by brian
clean slate
100
};
101
102
static const char *plugin_declarations_sym= "_mysql_plugin_declarations_";
103
104
/* Note that 'int version' must be the first field of every plugin
105
   sub-structure (plugin->info).
106
*/
107
108
static bool initialized= 0;
109
110
static DYNAMIC_ARRAY plugin_dl_array;
111
static DYNAMIC_ARRAY plugin_array;
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
112
static HASH plugin_hash[DRIZZLE_MAX_PLUGIN_TYPE_NUM];
1 by brian
clean slate
113
static bool reap_needed= false;
114
static int plugin_array_version=0;
115
116
/*
117
  write-lock on LOCK_system_variables_hash is required before modifying
118
  the following variables/structures
119
*/
120
static MEM_ROOT plugin_mem_root;
482 by Brian Aker
Remove uint.
121
static uint32_t global_variables_dynamic_size= 0;
1 by brian
clean slate
122
static HASH bookmark_hash;
123
124
125
/*
126
  hidden part of opaque value passed to variable check functions.
127
  Used to provide a object-like structure to non C++ consumers.
128
*/
129
struct st_item_value_holder : public st_mysql_value
130
{
131
  Item *item;
132
};
133
134
135
/*
136
  stored in bookmark_hash, this structure is never removed from the
520.1.22 by Brian Aker
Second pass of thd cleanup
137
  hash and is used to mark a single offset for a session local variable
1 by brian
clean slate
138
  even if plugins have been uninstalled and reinstalled, repeatedly.
139
  This structure is allocated from plugin_mem_root.
140
141
  The key format is as follows:
142
    1 byte         - variable type code
143
    name_len bytes - variable name
144
    '\0'           - end of key
145
*/
146
struct st_bookmark
147
{
482 by Brian Aker
Remove uint.
148
  uint32_t name_len;
1 by brian
clean slate
149
  int offset;
482 by Brian Aker
Remove uint.
150
  uint32_t version;
1 by brian
clean slate
151
  char key[1];
152
};
153
154
155
/*
156
  skeleton of a plugin variable - portion of structure common to all.
157
*/
158
struct st_mysql_sys_var
159
{
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
160
  DRIZZLE_PLUGIN_VAR_HEADER;
1 by brian
clean slate
161
};
162
163
164
/*
165
  sys_var class for access to all plugin variables visible to the user
166
*/
167
class sys_var_pluginvar: public sys_var
168
{
169
public:
170
  struct st_plugin_int *plugin;
171
  struct st_mysql_sys_var *plugin_var;
172
173
  static void *operator new(size_t size, MEM_ROOT *mem_root)
174
  { return (void*) alloc_root(mem_root, (uint) size); }
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
175
  static void operator delete(void *ptr_arg __attribute__((unused)),
176
                              size_t size __attribute__((unused)))
1 by brian
clean slate
177
  { TRASH(ptr_arg, size); }
178
179
  sys_var_pluginvar(const char *name_arg,
180
                    struct st_mysql_sys_var *plugin_var_arg)
181
    :sys_var(name_arg), plugin_var(plugin_var_arg) {}
182
  sys_var_pluginvar *cast_pluginvar() { return this; }
183
  bool is_readonly() const { return plugin_var->flags & PLUGIN_VAR_READONLY; }
184
  bool check_type(enum_var_type type)
520.1.21 by Brian Aker
THD -> Session rename
185
  { return !(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) && type != OPT_GLOBAL; }
1 by brian
clean slate
186
  bool check_update_type(Item_result type);
187
  SHOW_TYPE show_type();
520.1.22 by Brian Aker
Second pass of thd cleanup
188
  unsigned char* real_value_ptr(Session *session, enum_var_type type);
1 by brian
clean slate
189
  TYPELIB* plugin_var_typelib(void);
520.1.22 by Brian Aker
Second pass of thd cleanup
190
  unsigned char* value_ptr(Session *session, enum_var_type type, LEX_STRING *base);
191
  bool check(Session *session, set_var *var);
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
192
  bool check_default(enum_var_type type __attribute__((unused)))
77.1.46 by Monty Taylor
Finished the warnings work!
193
    { return is_readonly(); }
520.1.22 by Brian Aker
Second pass of thd cleanup
194
  void set_default(Session *session,
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
195
                   enum_var_type type __attribute__((unused)));
520.1.22 by Brian Aker
Second pass of thd cleanup
196
  bool update(Session *session, set_var *var);
1 by brian
clean slate
197
};
198
199
200
/* prototypes */
201
static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
202
                             const char *list);
203
static int test_plugin_options(MEM_ROOT *, struct st_plugin_int *,
135 by Brian Aker
Random cleanup. Dead partition tests, pass operator in sql_plugin, mtr based
204
                               int *, char **);
1 by brian
clean slate
205
static bool register_builtin(struct st_mysql_plugin *, struct st_plugin_int *,
206
                             struct st_plugin_int **);
520.1.22 by Brian Aker
Second pass of thd cleanup
207
static void unlock_variables(Session *session, struct system_variables *vars);
208
static void cleanup_variables(Session *session, struct system_variables *vars);
1 by brian
clean slate
209
static void plugin_vars_free_values(sys_var *vars);
210
static void plugin_opt_set_limits(struct my_option *options,
211
                                  const struct st_mysql_sys_var *opt);
212
#define my_intern_plugin_lock(A,B) intern_plugin_lock(A,B CALLER_INFO)
213
#define my_intern_plugin_lock_ci(A,B) intern_plugin_lock(A,B ORIG_CALLER_INFO)
214
static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref plugin
215
                                     CALLER_INFO_PROTO);
216
static void intern_plugin_unlock(LEX *lex, plugin_ref plugin);
217
static void reap_plugins(void);
218
219
220
/* declared in set_var.cc */
482 by Brian Aker
Remove uint.
221
extern sys_var *intern_find_sys_var(const char *str, uint32_t length, bool no_error);
520.1.22 by Brian Aker
Second pass of thd cleanup
222
extern bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
152 by Brian Aker
longlong replacement
223
                                 const char *name, int64_t val);
1 by brian
clean slate
224
225
/****************************************************************************
226
  Value type thunks, allows the C world to play in the C++ world
227
****************************************************************************/
228
229
static int item_value_type(struct st_mysql_value *value)
230
{
231
  switch (((st_item_value_holder*)value)->item->result_type()) {
232
  case INT_RESULT:
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
233
    return DRIZZLE_VALUE_TYPE_INT;
1 by brian
clean slate
234
  case REAL_RESULT:
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
235
    return DRIZZLE_VALUE_TYPE_REAL;
1 by brian
clean slate
236
  default:
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
237
    return DRIZZLE_VALUE_TYPE_STRING;
1 by brian
clean slate
238
  }
239
}
240
241
static const char *item_val_str(struct st_mysql_value *value,
242
                                char *buffer, int *length)
243
{
244
  String str(buffer, *length, system_charset_info), *res;
245
  if (!(res= ((st_item_value_holder*)value)->item->val_str(&str)))
246
    return NULL;
247
  *length= res->length();
248
  if (res->c_ptr_quick() == buffer)
249
    return buffer;
250
251
  /*
252
    Lets be nice and create a temporary string since the
253
    buffer was too small
254
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
255
  return current_session->strmake(res->c_ptr_quick(), res->length());
1 by brian
clean slate
256
}
257
258
53.2.2 by Monty Taylor
Updated everything that needs updating to compile with -std=gnu99 -pedantic
259
static int item_val_int(struct st_mysql_value *value, int64_t *buf)
1 by brian
clean slate
260
{
261
  Item *item= ((st_item_value_holder*)value)->item;
262
  *buf= item->val_int();
263
  if (item->is_null())
264
    return 1;
265
  return 0;
266
}
267
268
269
static int item_val_real(struct st_mysql_value *value, double *buf)
270
{
271
  Item *item= ((st_item_value_holder*)value)->item;
272
  *buf= item->val_real();
273
  if (item->is_null())
274
    return 1;
275
  return 0;
276
}
277
278
279
/****************************************************************************
280
  Plugin support code
281
****************************************************************************/
282
283
static struct st_plugin_dl *plugin_dl_find(const LEX_STRING *dl)
284
{
482 by Brian Aker
Remove uint.
285
  uint32_t i;
1 by brian
clean slate
286
  struct st_plugin_dl *tmp;
287
  for (i= 0; i < plugin_dl_array.elements; i++)
288
  {
289
    tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
290
    if (tmp->ref_count &&
291
        ! my_strnncoll(files_charset_info,
481 by Brian Aker
Remove all of uchar.
292
                       (const unsigned char *)dl->str, dl->length,
293
                       (const unsigned char *)tmp->dl.str, tmp->dl.length))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
294
      return(tmp);
1 by brian
clean slate
295
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
296
  return(0);
1 by brian
clean slate
297
}
298
299
static st_plugin_dl *plugin_dl_insert_or_reuse(struct st_plugin_dl *plugin_dl)
300
{
482 by Brian Aker
Remove uint.
301
  uint32_t i;
1 by brian
clean slate
302
  struct st_plugin_dl *tmp;
303
  for (i= 0; i < plugin_dl_array.elements; i++)
304
  {
305
    tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
306
    if (! tmp->ref_count)
307
    {
308
      memcpy(tmp, plugin_dl, sizeof(struct st_plugin_dl));
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
309
      return(tmp);
1 by brian
clean slate
310
    }
311
  }
481 by Brian Aker
Remove all of uchar.
312
  if (insert_dynamic(&plugin_dl_array, (unsigned char*)&plugin_dl))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
313
    return(0);
1 by brian
clean slate
314
  tmp= *dynamic_element(&plugin_dl_array, plugin_dl_array.elements - 1,
315
                        struct st_plugin_dl **)=
481 by Brian Aker
Remove all of uchar.
316
      (struct st_plugin_dl *) memdup_root(&plugin_mem_root, (unsigned char*)plugin_dl,
1 by brian
clean slate
317
                                           sizeof(struct st_plugin_dl));
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
318
  return(tmp);
1 by brian
clean slate
319
}
320
321
static inline void free_plugin_mem(struct st_plugin_dl *p)
322
{
323
  if (p->handle)
324
    dlclose(p->handle);
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
325
  free(p->dl.str);
1 by brian
clean slate
326
}
327
328
329
static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
330
{
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
331
  string dlpath;
332
  uint32_t plugin_dir_len, dummy_errors;
1 by brian
clean slate
333
  struct st_plugin_dl *tmp, plugin_dl;
334
  void *sym;
335
  plugin_dir_len= strlen(opt_plugin_dir);
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
336
  dlpath.reserve(FN_REFLEN);
1 by brian
clean slate
337
  /*
338
    Ensure that the dll doesn't have a path.
339
    This is done to ensure that only approved libraries from the
340
    plugin directory are used (to make this even remotely secure).
341
  */
266.1.26 by Monty Taylor
Removed my_strchr.
342
  if (strchr(dl->str, FN_LIBCHAR) ||
1 by brian
clean slate
343
      check_string_char_length((LEX_STRING *) dl, "", NAME_CHAR_LEN,
344
                               system_charset_info, 1) ||
345
      plugin_dir_len + dl->length + 1 >= FN_REFLEN)
346
  {
347
    if (report & REPORT_TO_USER)
348
      my_error(ER_UDF_NO_PATHS, MYF(0));
349
    if (report & REPORT_TO_LOG)
512.1.21 by Stewart Smith
sql_plugin.cc:330: error: format not a string literal and no format arguments
350
      sql_print_error("%s",ER(ER_UDF_NO_PATHS));
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
351
    return(0);
1 by brian
clean slate
352
  }
353
  /* If this dll is already loaded just increase ref_count. */
354
  if ((tmp= plugin_dl_find(dl)))
355
  {
356
    tmp->ref_count++;
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
357
    return(tmp);
1 by brian
clean slate
358
  }
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
359
  memset(&plugin_dl, 0, sizeof(plugin_dl));
1 by brian
clean slate
360
  /* Compile dll path */
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
361
  dlpath.append(opt_plugin_dir);
362
  dlpath.append("/");
363
  dlpath.append(dl->str);
1 by brian
clean slate
364
  plugin_dl.ref_count= 1;
365
  /* Open new dll handle */
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
366
  if (!(plugin_dl.handle= dlopen(dlpath.c_str(), RTLD_LAZY|RTLD_GLOBAL)))
1 by brian
clean slate
367
  {
368
    const char *errmsg=dlerror();
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
369
    uint32_t dlpathlen= dlpath.length();
370
    if (!dlpath.compare(0, dlpathlen, errmsg))
1 by brian
clean slate
371
    { // if errmsg starts from dlpath, trim this prefix.
372
      errmsg+=dlpathlen;
373
      if (*errmsg == ':') errmsg++;
374
      if (*errmsg == ' ') errmsg++;
375
    }
376
    if (report & REPORT_TO_USER)
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
377
      my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath.c_str(), errno, errmsg);
1 by brian
clean slate
378
    if (report & REPORT_TO_LOG)
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
379
      sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dlpath.c_str(), errno, errmsg);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
380
    return(0);
1 by brian
clean slate
381
  }
177.4.1 by mark
remove some useless version checking code from sql_plugin.cc
382
1 by brian
clean slate
383
  /* Find plugin declarations */
384
  if (!(sym= dlsym(plugin_dl.handle, plugin_declarations_sym)))
385
  {
386
    free_plugin_mem(&plugin_dl);
387
    if (report & REPORT_TO_USER)
388
      my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_declarations_sym);
389
    if (report & REPORT_TO_LOG)
390
      sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), plugin_declarations_sym);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
391
    return(0);
1 by brian
clean slate
392
  }
393
394
  plugin_dl.plugins= (struct st_mysql_plugin *)sym;
395
396
  /* Duplicate and convert dll name */
397
  plugin_dl.dl.length= dl->length * files_charset_info->mbmaxlen + 1;
398
  if (! (plugin_dl.dl.str= (char*) my_malloc(plugin_dl.dl.length, MYF(0))))
399
  {
400
    free_plugin_mem(&plugin_dl);
401
    if (report & REPORT_TO_USER)
402
      my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length);
403
    if (report & REPORT_TO_LOG)
404
      sql_print_error(ER(ER_OUTOFMEMORY), plugin_dl.dl.length);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
405
    return(0);
1 by brian
clean slate
406
  }
407
  plugin_dl.dl.length= copy_and_convert(plugin_dl.dl.str, plugin_dl.dl.length,
408
    files_charset_info, dl->str, dl->length, system_charset_info,
409
    &dummy_errors);
410
  plugin_dl.dl.str[plugin_dl.dl.length]= 0;
411
  /* Add this dll to array */
412
  if (! (tmp= plugin_dl_insert_or_reuse(&plugin_dl)))
413
  {
414
    free_plugin_mem(&plugin_dl);
415
    if (report & REPORT_TO_USER)
416
      my_error(ER_OUTOFMEMORY, MYF(0), sizeof(struct st_plugin_dl));
417
    if (report & REPORT_TO_LOG)
418
      sql_print_error(ER(ER_OUTOFMEMORY), sizeof(struct st_plugin_dl));
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
419
    return(0);
1 by brian
clean slate
420
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
421
  return(tmp);
1 by brian
clean slate
422
}
423
424
425
static void plugin_dl_del(const LEX_STRING *dl)
426
{
482 by Brian Aker
Remove uint.
427
  uint32_t i;
1 by brian
clean slate
428
429
  for (i= 0; i < plugin_dl_array.elements; i++)
430
  {
431
    struct st_plugin_dl *tmp= *dynamic_element(&plugin_dl_array, i,
432
                                               struct st_plugin_dl **);
433
    if (tmp->ref_count &&
434
        ! my_strnncoll(files_charset_info,
481 by Brian Aker
Remove all of uchar.
435
                       (const unsigned char *)dl->str, dl->length,
436
                       (const unsigned char *)tmp->dl.str, tmp->dl.length))
1 by brian
clean slate
437
    {
438
      /* Do not remove this element, unless no other plugin uses this dll. */
439
      if (! --tmp->ref_count)
440
      {
441
        free_plugin_mem(tmp);
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
442
        memset(tmp, 0, sizeof(struct st_plugin_dl));
1 by brian
clean slate
443
      }
444
      break;
445
    }
446
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
447
  return;
1 by brian
clean slate
448
}
449
450
451
static struct st_plugin_int *plugin_find_internal(const LEX_STRING *name, int type)
452
{
482 by Brian Aker
Remove uint.
453
  uint32_t i;
1 by brian
clean slate
454
  if (! initialized)
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
455
    return(0);
1 by brian
clean slate
456
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
457
  if (type == DRIZZLE_ANY_PLUGIN)
1 by brian
clean slate
458
  {
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
459
    for (i= 0; i < DRIZZLE_MAX_PLUGIN_TYPE_NUM; i++)
1 by brian
clean slate
460
    {
461
      struct st_plugin_int *plugin= (st_plugin_int *)
481 by Brian Aker
Remove all of uchar.
462
        hash_search(&plugin_hash[i], (const unsigned char *)name->str, name->length);
1 by brian
clean slate
463
      if (plugin)
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
464
        return(plugin);
1 by brian
clean slate
465
    }
466
  }
467
  else
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
468
    return((st_plugin_int *)
481 by Brian Aker
Remove all of uchar.
469
        hash_search(&plugin_hash[type], (const unsigned char *)name->str, name->length));
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
470
  return(0);
1 by brian
clean slate
471
}
472
473
474
static SHOW_COMP_OPTION plugin_status(const LEX_STRING *name, int type)
475
{
476
  SHOW_COMP_OPTION rc= SHOW_OPTION_NO;
477
  struct st_plugin_int *plugin;
478
  if ((plugin= plugin_find_internal(name, type)))
479
  {
480
    rc= SHOW_OPTION_DISABLED;
481
    if (plugin->state == PLUGIN_IS_READY)
482
      rc= SHOW_OPTION_YES;
483
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
484
  return(rc);
1 by brian
clean slate
485
}
486
487
488
bool plugin_is_ready(const LEX_STRING *name, int type)
489
{
163 by Brian Aker
Merge Monty's code.
490
  bool rc= false;
1 by brian
clean slate
491
  if (plugin_status(name, type) == SHOW_OPTION_YES)
163 by Brian Aker
Merge Monty's code.
492
    rc= true;
1 by brian
clean slate
493
  return rc;
494
}
495
496
497
SHOW_COMP_OPTION sys_var_have_plugin::get_option()
498
{
499
  LEX_STRING plugin_name= { (char *) plugin_name_str, plugin_name_len };
500
  return plugin_status(&plugin_name, plugin_type);
501
}
502
503
504
static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc CALLER_INFO_PROTO)
505
{
506
  st_plugin_int *pi= plugin_ref_to_int(rc);
507
508
  if (pi->state & (PLUGIN_IS_READY | PLUGIN_IS_UNINITIALIZED))
509
  {
510
    plugin_ref plugin;
511
    /*
512
      For debugging, we do an additional malloc which allows the
513
      memory manager and/or valgrind to track locked references and
514
      double unlocks to aid resolving reference counting.problems.
515
    */
516
    if (!(plugin= (plugin_ref) my_malloc_ci(sizeof(pi), MYF(MY_WME))))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
517
      return(NULL);
1 by brian
clean slate
518
519
    *plugin= pi;
520
    pi->ref_count++;
521
522
    if (lex)
481 by Brian Aker
Remove all of uchar.
523
      insert_dynamic(&lex->plugins, (unsigned char*)&plugin);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
524
    return(plugin);
1 by brian
clean slate
525
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
526
  return(NULL);
1 by brian
clean slate
527
}
528
529
520.1.22 by Brian Aker
Second pass of thd cleanup
530
plugin_ref plugin_lock(Session *session, plugin_ref *ptr CALLER_INFO_PROTO)
1 by brian
clean slate
531
{
520.1.22 by Brian Aker
Second pass of thd cleanup
532
  LEX *lex= session ? session->lex : 0;
1 by brian
clean slate
533
  plugin_ref rc;
534
  rc= my_intern_plugin_lock_ci(lex, *ptr);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
535
  return(rc);
1 by brian
clean slate
536
}
537
538
520.1.22 by Brian Aker
Second pass of thd cleanup
539
plugin_ref plugin_lock_by_name(Session *session, const LEX_STRING *name, int type
1 by brian
clean slate
540
                               CALLER_INFO_PROTO)
541
{
520.1.22 by Brian Aker
Second pass of thd cleanup
542
  LEX *lex= session ? session->lex : 0;
1 by brian
clean slate
543
  plugin_ref rc= NULL;
544
  st_plugin_int *plugin;
545
  if ((plugin= plugin_find_internal(name, type)))
546
    rc= my_intern_plugin_lock_ci(lex, plugin_int_to_ref(plugin));
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
547
  return(rc);
1 by brian
clean slate
548
}
549
550
551
static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin)
552
{
482 by Brian Aker
Remove uint.
553
  uint32_t i;
1 by brian
clean slate
554
  struct st_plugin_int *tmp;
555
  for (i= 0; i < plugin_array.elements; i++)
556
  {
557
    tmp= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
558
    if (tmp->state == PLUGIN_IS_FREED)
559
    {
560
      memcpy(tmp, plugin, sizeof(struct st_plugin_int));
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
561
      return(tmp);
1 by brian
clean slate
562
    }
563
  }
481 by Brian Aker
Remove all of uchar.
564
  if (insert_dynamic(&plugin_array, (unsigned char*)&plugin))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
565
    return(0);
1 by brian
clean slate
566
  tmp= *dynamic_element(&plugin_array, plugin_array.elements - 1,
567
                        struct st_plugin_int **)=
481 by Brian Aker
Remove all of uchar.
568
       (struct st_plugin_int *) memdup_root(&plugin_mem_root, (unsigned char*)plugin,
1 by brian
clean slate
569
                                            sizeof(struct st_plugin_int));
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
570
  return(tmp);
1 by brian
clean slate
571
}
572
573
574
/*
575
  NOTE
576
    Requires that a write-lock is held on LOCK_system_variables_hash
577
*/
578
static bool plugin_add(MEM_ROOT *tmp_root,
579
                       const LEX_STRING *name, const LEX_STRING *dl,
580
                       int *argc, char **argv, int report)
581
{
582
  struct st_plugin_int tmp;
583
  struct st_mysql_plugin *plugin;
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
584
  if (plugin_find_internal(name, DRIZZLE_ANY_PLUGIN))
1 by brian
clean slate
585
  {
586
    if (report & REPORT_TO_USER)
587
      my_error(ER_UDF_EXISTS, MYF(0), name->str);
588
    if (report & REPORT_TO_LOG)
589
      sql_print_error(ER(ER_UDF_EXISTS), name->str);
163 by Brian Aker
Merge Monty's code.
590
    return(true);
1 by brian
clean slate
591
  }
592
  /* Clear the whole struct to catch future extensions. */
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
593
  memset(&tmp, 0, sizeof(tmp));
1 by brian
clean slate
594
  if (! (tmp.plugin_dl= plugin_dl_add(dl, report)))
163 by Brian Aker
Merge Monty's code.
595
    return(true);
1 by brian
clean slate
596
  /* Find plugin by name */
177.4.3 by mark
ripped out more plugin ABI and API version checking, and plugin versions are now strings
597
  for (plugin= tmp.plugin_dl->plugins; plugin->name; plugin++)
1 by brian
clean slate
598
  {
482 by Brian Aker
Remove uint.
599
    uint32_t name_len= strlen(plugin->name);
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
600
    if (plugin->type >= 0 && plugin->type < DRIZZLE_MAX_PLUGIN_TYPE_NUM &&
1 by brian
clean slate
601
        ! my_strnncoll(system_charset_info,
481 by Brian Aker
Remove all of uchar.
602
                       (const unsigned char *)name->str, name->length,
603
                       (const unsigned char *)plugin->name,
1 by brian
clean slate
604
                       name_len))
605
    {
606
      struct st_plugin_int *tmp_plugin_ptr;
177.4.1 by mark
remove some useless version checking code from sql_plugin.cc
607
1 by brian
clean slate
608
      tmp.plugin= plugin;
609
      tmp.name.str= (char *)plugin->name;
610
      tmp.name.length= name_len;
611
      tmp.ref_count= 0;
612
      tmp.state= PLUGIN_IS_UNINITIALIZED;
135 by Brian Aker
Random cleanup. Dead partition tests, pass operator in sql_plugin, mtr based
613
      if (!test_plugin_options(tmp_root, &tmp, argc, argv))
1 by brian
clean slate
614
      {
615
        if ((tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
616
        {
617
          plugin_array_version++;
481 by Brian Aker
Remove all of uchar.
618
          if (!my_hash_insert(&plugin_hash[plugin->type], (unsigned char*)tmp_plugin_ptr))
1 by brian
clean slate
619
          {
620
            init_alloc_root(&tmp_plugin_ptr->mem_root, 4096, 4096);
163 by Brian Aker
Merge Monty's code.
621
            return(false);
1 by brian
clean slate
622
          }
623
          tmp_plugin_ptr->state= PLUGIN_IS_FREED;
624
        }
625
        mysql_del_sys_var_chain(tmp.system_vars);
626
        goto err;
627
      }
628
      /* plugin was disabled */
629
      plugin_dl_del(dl);
163 by Brian Aker
Merge Monty's code.
630
      return(false);
1 by brian
clean slate
631
    }
632
  }
633
  if (report & REPORT_TO_USER)
634
    my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), name->str);
635
  if (report & REPORT_TO_LOG)
636
    sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), name->str);
637
err:
638
  plugin_dl_del(dl);
163 by Brian Aker
Merge Monty's code.
639
  return(true);
1 by brian
clean slate
640
}
641
642
643
static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check)
644
{
645
  if (plugin->plugin->status_vars)
646
  {
647
#ifdef FIX_LATER
648
    /*
649
      We have a problem right now where we can not prepend without
650
      breaking backwards compatibility. We will fix this shortly so
651
      that engines have "use names" and we wil use those for
652
      CREATE TABLE, and use the plugin name then for adding automatic
653
      variable names.
654
    */
655
    SHOW_VAR array[2]= {
656
      {plugin->plugin->name, (char*)plugin->plugin->status_vars, SHOW_ARRAY},
657
      {0, 0, SHOW_UNDEF}
658
    };
659
    remove_status_vars(array);
660
#else
661
    remove_status_vars(plugin->plugin->status_vars);
662
#endif /* FIX_LATER */
663
  }
664
665
  if (plugin_type_deinitialize[plugin->plugin->type])
666
  {
667
    if ((*plugin_type_deinitialize[plugin->plugin->type])(plugin))
668
    {
338 by Monty Taylor
Tagged more strings.
669
      sql_print_error(_("Plugin '%s' of type %s failed deinitialization"),
1 by brian
clean slate
670
                      plugin->name.str, plugin_type_names[plugin->plugin->type].str);
671
    }
672
  }
673
  else if (plugin->plugin->deinit)
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
674
    plugin->plugin->deinit(plugin);
675
1 by brian
clean slate
676
  plugin->state= PLUGIN_IS_UNINITIALIZED;
677
678
  /*
520.1.21 by Brian Aker
THD -> Session rename
679
    We do the check here because NDB has a worker Session which doesn't
1 by brian
clean slate
680
    exit until NDB is shut down.
681
  */
682
  if (ref_check && plugin->ref_count)
338 by Monty Taylor
Tagged more strings.
683
    sql_print_error(_("Plugin '%s' has ref_count=%d after deinitialization."),
1 by brian
clean slate
684
                    plugin->name.str, plugin->ref_count);
685
}
686
687
688
static void plugin_del(struct st_plugin_int *plugin)
689
{
690
  /* Free allocated strings before deleting the plugin. */
691
  plugin_vars_free_values(plugin->system_vars);
481 by Brian Aker
Remove all of uchar.
692
  hash_delete(&plugin_hash[plugin->plugin->type], (unsigned char*)plugin);
1 by brian
clean slate
693
  if (plugin->plugin_dl)
694
    plugin_dl_del(&plugin->plugin_dl->dl);
695
  plugin->state= PLUGIN_IS_FREED;
696
  plugin_array_version++;
697
  rw_wrlock(&LOCK_system_variables_hash);
698
  mysql_del_sys_var_chain(plugin->system_vars);
699
  rw_unlock(&LOCK_system_variables_hash);
700
  free_root(&plugin->mem_root, MYF(0));
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
701
  return;
1 by brian
clean slate
702
}
703
704
static void reap_plugins(void)
705
{
482 by Brian Aker
Remove uint.
706
  uint32_t count, idx;
1 by brian
clean slate
707
  struct st_plugin_int *plugin, **reap, **list;
708
709
  if (!reap_needed)
710
    return;
711
712
  reap_needed= false;
713
  count= plugin_array.elements;
714
  reap= (struct st_plugin_int **)my_alloca(sizeof(plugin)*(count+1));
715
  *(reap++)= NULL;
716
717
  for (idx= 0; idx < count; idx++)
718
  {
719
    plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
720
    if (plugin->state == PLUGIN_IS_DELETED && !plugin->ref_count)
721
    {
722
      /* change the status flag to prevent reaping by another thread */
723
      plugin->state= PLUGIN_IS_DYING;
724
      *(reap++)= plugin;
725
    }
726
  }
727
728
  list= reap;
729
  while ((plugin= *(--list)))
730
    plugin_deinitialize(plugin, true);
731
732
  while ((plugin= *(--reap)))
733
    plugin_del(plugin);
734
735
  my_afree(reap);
736
}
737
738
static void intern_plugin_unlock(LEX *lex, plugin_ref plugin)
739
{
740
  int i;
741
  st_plugin_int *pi;
742
743
  if (!plugin)
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
744
    return;
1 by brian
clean slate
745
746
  pi= plugin_ref_to_int(plugin);
747
481 by Brian Aker
Remove all of uchar.
748
  free((unsigned char*) plugin);
1 by brian
clean slate
749
750
  if (lex)
751
  {
752
    /*
753
      Remove one instance of this plugin from the use list.
754
      We are searching backwards so that plugins locked last
755
      could be unlocked faster - optimizing for LIFO semantics.
756
    */
757
    for (i= lex->plugins.elements - 1; i >= 0; i--)
758
      if (plugin == *dynamic_element(&lex->plugins, i, plugin_ref*))
759
      {
760
        delete_dynamic_element(&lex->plugins, i);
761
        break;
762
      }
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
763
    assert(i >= 0);
1 by brian
clean slate
764
  }
765
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
766
  assert(pi->ref_count);
1 by brian
clean slate
767
  pi->ref_count--;
768
769
  if (pi->state == PLUGIN_IS_DELETED && !pi->ref_count)
770
    reap_needed= true;
771
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
772
  return;
1 by brian
clean slate
773
}
774
775
520.1.22 by Brian Aker
Second pass of thd cleanup
776
void plugin_unlock(Session *session, plugin_ref plugin)
1 by brian
clean slate
777
{
520.1.22 by Brian Aker
Second pass of thd cleanup
778
  LEX *lex= session ? session->lex : 0;
1 by brian
clean slate
779
  if (!plugin)
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
780
    return;
1 by brian
clean slate
781
  intern_plugin_unlock(lex, plugin);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
782
  return;
1 by brian
clean slate
783
}
784
785
520.1.22 by Brian Aker
Second pass of thd cleanup
786
void plugin_unlock_list(Session *session, plugin_ref *list, uint32_t count)
1 by brian
clean slate
787
{
520.1.22 by Brian Aker
Second pass of thd cleanup
788
  LEX *lex= session ? session->lex : 0;
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
789
  assert(list);
1 by brian
clean slate
790
  while (count--)
791
    intern_plugin_unlock(lex, *list++);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
792
  return;
1 by brian
clean slate
793
}
794
795
796
static int plugin_initialize(struct st_plugin_int *plugin)
797
{
798
799
  if (plugin_type_initialize[plugin->plugin->type])
800
  {
801
    if ((*plugin_type_initialize[plugin->plugin->type])(plugin))
802
    {
338 by Monty Taylor
Tagged more strings.
803
      sql_print_error(_("Plugin '%s' registration as a %s failed."),
1 by brian
clean slate
804
                      plugin->name.str, plugin_type_names[plugin->plugin->type].str);
805
      goto err;
806
    }
807
  }
808
  else if (plugin->plugin->init)
809
  {
810
    if (plugin->plugin->init(plugin))
811
    {
338 by Monty Taylor
Tagged more strings.
812
      sql_print_error(_("Plugin '%s' init function returned error."),
1 by brian
clean slate
813
                      plugin->name.str);
814
      goto err;
815
    }
816
  }
817
818
  plugin->state= PLUGIN_IS_READY;
819
820
  if (plugin->plugin->status_vars)
821
  {
822
#ifdef FIX_LATER
823
    /*
824
      We have a problem right now where we can not prepend without
825
      breaking backwards compatibility. We will fix this shortly so
826
      that engines have "use names" and we wil use those for
827
      CREATE TABLE, and use the plugin name then for adding automatic
828
      variable names.
829
    */
830
    SHOW_VAR array[2]= {
831
      {plugin->plugin->name, (char*)plugin->plugin->status_vars, SHOW_ARRAY},
832
      {0, 0, SHOW_UNDEF}
833
    };
834
    if (add_status_vars(array)) // add_status_vars makes a copy
835
      goto err;
836
#else
837
    add_status_vars(plugin->plugin->status_vars); // add_status_vars makes a copy
838
#endif /* FIX_LATER */
839
  }
840
841
  /*
842
    set the plugin attribute of plugin's sys vars so they are pointing
843
    to the active plugin
844
  */
845
  if (plugin->system_vars)
846
  {
847
    sys_var_pluginvar *var= plugin->system_vars->cast_pluginvar();
848
    for (;;)
849
    {
850
      var->plugin= plugin;
851
      if (!var->next)
852
        break;
853
      var= var->next->cast_pluginvar();
854
    }
855
  }
856
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
857
  return(0);
1 by brian
clean slate
858
err:
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
859
  return(1);
1 by brian
clean slate
860
}
861
862
481 by Brian Aker
Remove all of uchar.
863
extern "C" unsigned char *get_plugin_hash_key(const unsigned char *, size_t *, bool);
864
extern "C" unsigned char *get_bookmark_hash_key(const unsigned char *, size_t *, bool);
865
866
867
unsigned char *get_plugin_hash_key(const unsigned char *buff, size_t *length,
146 by Brian Aker
my_bool cleanup.
868
                           bool not_used __attribute__((unused)))
1 by brian
clean slate
869
{
870
  struct st_plugin_int *plugin= (st_plugin_int *)buff;
871
  *length= (uint)plugin->name.length;
481 by Brian Aker
Remove all of uchar.
872
  return((unsigned char *)plugin->name.str);
1 by brian
clean slate
873
}
874
875
481 by Brian Aker
Remove all of uchar.
876
unsigned char *get_bookmark_hash_key(const unsigned char *buff, size_t *length,
146 by Brian Aker
my_bool cleanup.
877
                             bool not_used __attribute__((unused)))
1 by brian
clean slate
878
{
879
  struct st_bookmark *var= (st_bookmark *)buff;
880
  *length= var->name_len + 1;
481 by Brian Aker
Remove all of uchar.
881
  return (unsigned char*) var->key;
1 by brian
clean slate
882
}
883
884
885
/*
886
  The logic is that we first load and initialize all compiled in plugins.
887
  From there we load up the dynamic types (assuming we have not been told to
888
  skip this part).
889
890
  Finally we initialize everything, aka the dynamic that have yet to initialize.
891
*/
892
int plugin_init(int *argc, char **argv, int flags)
893
{
482 by Brian Aker
Remove uint.
894
  uint32_t i;
1 by brian
clean slate
895
  struct st_mysql_plugin **builtins;
896
  struct st_mysql_plugin *plugin;
897
  struct st_plugin_int tmp, *plugin_ptr, **reap;
898
  MEM_ROOT tmp_root;
899
900
  if (initialized)
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
901
    return(0);
1 by brian
clean slate
902
903
  init_alloc_root(&plugin_mem_root, 4096, 4096);
904
  init_alloc_root(&tmp_root, 4096, 4096);
905
906
  if (hash_init(&bookmark_hash, &my_charset_bin, 16, 0, 0,
907
                  get_bookmark_hash_key, NULL, HASH_UNIQUE))
908
      goto err;
909
910
911
  if (my_init_dynamic_array(&plugin_dl_array,
912
                            sizeof(struct st_plugin_dl *),16,16) ||
913
      my_init_dynamic_array(&plugin_array,
914
                            sizeof(struct st_plugin_int *),16,16))
915
    goto err;
916
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
917
  for (i= 0; i < DRIZZLE_MAX_PLUGIN_TYPE_NUM; i++)
1 by brian
clean slate
918
  {
919
    if (hash_init(&plugin_hash[i], system_charset_info, 16, 0, 0,
920
                  get_plugin_hash_key, NULL, HASH_UNIQUE))
921
      goto err;
922
  }
923
924
  initialized= 1;
925
926
  /*
927
    First we register builtin plugins
928
  */
929
  for (builtins= mysqld_builtins; *builtins; builtins++)
930
  {
177.4.3 by mark
ripped out more plugin ABI and API version checking, and plugin versions are now strings
931
    for (plugin= *builtins; plugin->name; plugin++)
1 by brian
clean slate
932
    {
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
933
      memset(&tmp, 0, sizeof(tmp));
1 by brian
clean slate
934
      tmp.plugin= plugin;
935
      tmp.name.str= (char *)plugin->name;
936
      tmp.name.length= strlen(plugin->name);
937
938
      free_root(&tmp_root, MYF(MY_MARK_BLOCKS_FREE));
135 by Brian Aker
Random cleanup. Dead partition tests, pass operator in sql_plugin, mtr based
939
      if (test_plugin_options(&tmp_root, &tmp, argc, argv))
1 by brian
clean slate
940
        continue;
941
942
      if (register_builtin(plugin, &tmp, &plugin_ptr))
943
        goto err_unlock;
944
945
      if (plugin_initialize(plugin_ptr))
946
        goto err_unlock;
947
948
      /*
949
        initialize the global default storage engine so that it may
950
        not be null in any child thread.
951
      */
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
952
      if (my_strcasecmp(&my_charset_utf8_general_ci, plugin->name, "MyISAM") == 0)
1 by brian
clean slate
953
      {
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
954
        assert(!global_system_variables.table_plugin);
1 by brian
clean slate
955
        global_system_variables.table_plugin=
956
          my_intern_plugin_lock(NULL, plugin_int_to_ref(plugin_ptr));
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
957
        assert(plugin_ptr->ref_count == 1);
1 by brian
clean slate
958
      }
959
    }
960
  }
961
962
  /* should now be set to MyISAM storage engine */
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
963
  assert(global_system_variables.table_plugin);
1 by brian
clean slate
964
965
  /* Register all dynamic plugins */
966
  if (!(flags & PLUGIN_INIT_SKIP_DYNAMIC_LOADING))
967
  {
968
    if (opt_plugin_load)
969
      plugin_load_list(&tmp_root, argc, argv, opt_plugin_load);
970
  }
971
972
  if (flags & PLUGIN_INIT_SKIP_INITIALIZATION)
973
    goto end;
974
975
  /*
976
    Now we initialize all remaining plugins
977
  */
978
979
  reap= (st_plugin_int **) my_alloca((plugin_array.elements+1) * sizeof(void*));
980
  *(reap++)= NULL;
981
982
  for (i= 0; i < plugin_array.elements; i++)
983
  {
984
    plugin_ptr= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
985
    if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED)
986
    {
987
      if (plugin_initialize(plugin_ptr))
988
      {
989
        plugin_ptr->state= PLUGIN_IS_DYING;
990
        *(reap++)= plugin_ptr;
991
      }
992
    }
993
  }
994
995
  /*
996
    Check if any plugins have to be reaped
997
  */
998
  while ((plugin_ptr= *(--reap)))
999
  {
1000
    plugin_deinitialize(plugin_ptr, true);
1001
    plugin_del(plugin_ptr);
1002
  }
1003
1004
  my_afree(reap);
1005
1006
end:
1007
  free_root(&tmp_root, MYF(0));
1008
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1009
  return(0);
1 by brian
clean slate
1010
1011
err_unlock:
1012
err:
1013
  free_root(&tmp_root, MYF(0));
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1014
  return(1);
1 by brian
clean slate
1015
}
1016
1017
1018
static bool register_builtin(struct st_mysql_plugin *plugin,
1019
                             struct st_plugin_int *tmp,
1020
                             struct st_plugin_int **ptr)
1021
{
1022
1023
  tmp->state= PLUGIN_IS_UNINITIALIZED;
1024
  tmp->ref_count= 0;
1025
  tmp->plugin_dl= 0;
1026
481 by Brian Aker
Remove all of uchar.
1027
  if (insert_dynamic(&plugin_array, (unsigned char*)&tmp))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1028
    return(1);
1 by brian
clean slate
1029
1030
  *ptr= *dynamic_element(&plugin_array, plugin_array.elements - 1,
1031
                         struct st_plugin_int **)=
481 by Brian Aker
Remove all of uchar.
1032
        (struct st_plugin_int *) memdup_root(&plugin_mem_root, (unsigned char*)tmp,
1 by brian
clean slate
1033
                                             sizeof(struct st_plugin_int));
1034
481 by Brian Aker
Remove all of uchar.
1035
  if (my_hash_insert(&plugin_hash[plugin->type],(unsigned char*) *ptr))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1036
    return(1);
1 by brian
clean slate
1037
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1038
  return(0);
1 by brian
clean slate
1039
}
1040
1041
1042
/*
1043
  called only by plugin_init()
1044
*/
1045
static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
1046
                             const char *list)
1047
{
1048
  char buffer[FN_REFLEN];
1049
  LEX_STRING name= {buffer, 0}, dl= {NULL, 0}, *str= &name;
1050
  struct st_plugin_dl *plugin_dl;
1051
  struct st_mysql_plugin *plugin;
1052
  char *p= buffer;
1053
  while (list)
1054
  {
1055
    if (p == buffer + sizeof(buffer) - 1)
1056
    {
338 by Monty Taylor
Tagged more strings.
1057
      sql_print_error(_("plugin-load parameter too long"));
163 by Brian Aker
Merge Monty's code.
1058
      return(true);
1 by brian
clean slate
1059
    }
1060
1061
    switch ((*(p++)= *(list++))) {
1062
    case '\0':
1063
      list= NULL; /* terminate the loop */
1064
      /* fall through */
1065
    case ':':     /* can't use this as delimiter as it may be drive letter */
1066
    case ';':
1067
      str->str[str->length]= '\0';
1068
      if (str == &name)  // load all plugins in named module
1069
      {
1070
        if (!name.length)
1071
        {
1072
          p--;    /* reset pointer */
1073
          continue;
1074
        }
1075
1076
        dl= name;
1077
        if ((plugin_dl= plugin_dl_add(&dl, REPORT_TO_LOG)))
1078
        {
177.4.3 by mark
ripped out more plugin ABI and API version checking, and plugin versions are now strings
1079
          for (plugin= plugin_dl->plugins; plugin->name; plugin++)
1 by brian
clean slate
1080
          {
1081
            name.str= (char *) plugin->name;
1082
            name.length= strlen(name.str);
1083
1084
            free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
1085
            if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
1086
              goto error;
1087
          }
1088
          plugin_dl_del(&dl); // reduce ref count
1089
        }
1090
      }
1091
      else
1092
      {
1093
        free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
1094
        if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
1095
          goto error;
1096
      }
1097
      name.length= dl.length= 0;
1098
      dl.str= NULL; name.str= p= buffer;
1099
      str= &name;
1100
      continue;
1101
    case '=':
1102
    case '#':
1103
      if (str == &name)
1104
      {
1105
        name.str[name.length]= '\0';
1106
        str= &dl;
1107
        str->str= p;
1108
        continue;
1109
      }
1110
    default:
1111
      str->length++;
1112
      continue;
1113
    }
1114
  }
163 by Brian Aker
Merge Monty's code.
1115
  return(false);
1 by brian
clean slate
1116
error:
338 by Monty Taylor
Tagged more strings.
1117
  sql_print_error(_("Couldn't load plugin named '%s' with soname '%s'."),
1 by brian
clean slate
1118
                  name.str, dl.str);
163 by Brian Aker
Merge Monty's code.
1119
  return(true);
1 by brian
clean slate
1120
}
1121
1122
1123
void plugin_shutdown(void)
1124
{
482 by Brian Aker
Remove uint.
1125
  uint32_t i, count= plugin_array.elements, free_slots= 0;
1 by brian
clean slate
1126
  struct st_plugin_int **plugins, *plugin;
1127
  struct st_plugin_dl **dl;
1128
1129
  if (initialized)
1130
  {
1131
    reap_needed= true;
1132
1133
    /*
1134
      We want to shut down plugins in a reasonable order, this will
1135
      become important when we have plugins which depend upon each other.
1136
      Circular references cannot be reaped so they are forced afterwards.
1137
      TODO: Have an additional step here to notify all active plugins that
1138
      shutdown is requested to allow plugins to deinitialize in parallel.
1139
    */
1140
    while (reap_needed && (count= plugin_array.elements))
1141
    {
1142
      reap_plugins();
1143
      for (i= free_slots= 0; i < count; i++)
1144
      {
1145
        plugin= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
1146
        switch (plugin->state) {
1147
        case PLUGIN_IS_READY:
1148
          plugin->state= PLUGIN_IS_DELETED;
1149
          reap_needed= true;
1150
          break;
1151
        case PLUGIN_IS_FREED:
1152
        case PLUGIN_IS_UNINITIALIZED:
1153
          free_slots++;
1154
          break;
1155
        }
1156
      }
1157
      if (!reap_needed)
1158
      {
1159
        /*
1160
          release any plugin references held.
1161
        */
1162
        unlock_variables(NULL, &global_system_variables);
1163
        unlock_variables(NULL, &max_system_variables);
1164
      }
1165
    }
1166
1167
    if (count > free_slots)
338 by Monty Taylor
Tagged more strings.
1168
      sql_print_warning(_("Forcing shutdown of %d plugins"),
1169
                        count - free_slots);
1 by brian
clean slate
1170
1171
    plugins= (struct st_plugin_int **) my_alloca(sizeof(void*) * (count+1));
1172
1173
    /*
1174
      If we have any plugins which did not die cleanly, we force shutdown
1175
    */
1176
    for (i= 0; i < count; i++)
1177
    {
1178
      plugins[i]= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
1179
      /* change the state to ensure no reaping races */
1180
      if (plugins[i]->state == PLUGIN_IS_DELETED)
1181
        plugins[i]->state= PLUGIN_IS_DYING;
1182
    }
1183
1184
    /*
1185
      We loop through all plugins and call deinit() if they have one.
1186
    */
1187
    for (i= 0; i < count; i++)
1188
      if (!(plugins[i]->state & (PLUGIN_IS_UNINITIALIZED | PLUGIN_IS_FREED)))
1189
      {
338 by Monty Taylor
Tagged more strings.
1190
        sql_print_information(_("Plugin '%s' will be forced to shutdown"),
1 by brian
clean slate
1191
                              plugins[i]->name.str);
1192
        /*
1193
          We are forcing deinit on plugins so we don't want to do a ref_count
1194
          check until we have processed all the plugins.
1195
        */
1196
        plugin_deinitialize(plugins[i], false);
1197
      }
1198
1199
    /*
1200
      We defer checking ref_counts until after all plugins are deinitialized
1201
      as some may have worker threads holding on to plugin references.
1202
    */
1203
    for (i= 0; i < count; i++)
1204
    {
1205
      if (plugins[i]->ref_count)
338 by Monty Taylor
Tagged more strings.
1206
        sql_print_error(_("Plugin '%s' has ref_count=%d after shutdown."),
1 by brian
clean slate
1207
                        plugins[i]->name.str, plugins[i]->ref_count);
1208
      if (plugins[i]->state & PLUGIN_IS_UNINITIALIZED)
1209
        plugin_del(plugins[i]);
1210
    }
1211
1212
    /*
1213
      Now we can deallocate all memory.
1214
    */
1215
1216
    cleanup_variables(NULL, &global_system_variables);
1217
    cleanup_variables(NULL, &max_system_variables);
1218
1219
    initialized= 0;
1220
1221
    my_afree(plugins);
1222
  }
1223
1224
  /* Dispose of the memory */
1225
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1226
  for (i= 0; i < DRIZZLE_MAX_PLUGIN_TYPE_NUM; i++)
1 by brian
clean slate
1227
    hash_free(&plugin_hash[i]);
1228
  delete_dynamic(&plugin_array);
1229
1230
  count= plugin_dl_array.elements;
1231
  dl= (struct st_plugin_dl **)my_alloca(sizeof(void*) * count);
1232
  for (i= 0; i < count; i++)
1233
    dl[i]= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
1234
  for (i= 0; i < plugin_dl_array.elements; i++)
1235
    free_plugin_mem(dl[i]);
1236
  my_afree(dl);
1237
  delete_dynamic(&plugin_dl_array);
1238
1239
  hash_free(&bookmark_hash);
1240
  free_root(&plugin_mem_root, MYF(0));
1241
1242
  global_variables_dynamic_size= 0;
1243
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1244
  return;
1 by brian
clean slate
1245
}
1246
1247
520.1.22 by Brian Aker
Second pass of thd cleanup
1248
bool plugin_foreach_with_mask(Session *session, plugin_foreach_func *func,
482 by Brian Aker
Remove uint.
1249
                       int type, uint32_t state_mask, void *arg)
1 by brian
clean slate
1250
{
482 by Brian Aker
Remove uint.
1251
  uint32_t idx, total;
1 by brian
clean slate
1252
  struct st_plugin_int *plugin, **plugins;
1253
  int version=plugin_array_version;
1254
1255
  if (!initialized)
163 by Brian Aker
Merge Monty's code.
1256
    return(false);
1 by brian
clean slate
1257
1258
  state_mask= ~state_mask; // do it only once
1259
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1260
  total= type == DRIZZLE_ANY_PLUGIN ? plugin_array.elements
1 by brian
clean slate
1261
                                  : plugin_hash[type].records;
1262
  /*
1263
    Do the alloca out here in case we do have a working alloca:
1264
        leaving the nested stack frame invalidates alloca allocation.
1265
  */
1266
  plugins=(struct st_plugin_int **)my_alloca(total*sizeof(plugin));
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1267
  if (type == DRIZZLE_ANY_PLUGIN)
1 by brian
clean slate
1268
  {
1269
    for (idx= 0; idx < total; idx++)
1270
    {
1271
      plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
1272
      plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL;
1273
    }
1274
  }
1275
  else
1276
  {
1277
    HASH *hash= plugin_hash + type;
1278
    for (idx= 0; idx < total; idx++)
1279
    {
1280
      plugin= (struct st_plugin_int *) hash_element(hash, idx);
1281
      plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL;
1282
    }
1283
  }
1284
  for (idx= 0; idx < total; idx++)
1285
  {
1286
    if (unlikely(version != plugin_array_version))
1287
    {
482 by Brian Aker
Remove uint.
1288
      for (uint32_t i=idx; i < total; i++)
1 by brian
clean slate
1289
        if (plugins[i] && plugins[i]->state & state_mask)
1290
          plugins[i]=0;
1291
    }
1292
    plugin= plugins[idx];
163 by Brian Aker
Merge Monty's code.
1293
    /* It will stop iterating on first engine error when "func" returns true */
520.1.22 by Brian Aker
Second pass of thd cleanup
1294
    if (plugin && func(session, plugin_int_to_ref(plugin), arg))
1 by brian
clean slate
1295
        goto err;
1296
  }
1297
1298
  my_afree(plugins);
163 by Brian Aker
Merge Monty's code.
1299
  return(false);
1 by brian
clean slate
1300
err:
1301
  my_afree(plugins);
163 by Brian Aker
Merge Monty's code.
1302
  return(true);
1 by brian
clean slate
1303
}
1304
1305
1306
/****************************************************************************
1307
  Internal type declarations for variables support
1308
****************************************************************************/
1309
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1310
#undef DRIZZLE_SYSVAR_NAME
1311
#define DRIZZLE_SYSVAR_NAME(name) name
1 by brian
clean slate
1312
#define PLUGIN_VAR_TYPEMASK 0x007f
1313
1314
#define EXTRA_OPTIONS 3 /* options for: 'foo', 'plugin-foo' and NULL */
1315
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1316
typedef DECLARE_DRIZZLE_SYSVAR_BASIC(sysvar_bool_t, bool);
520.1.22 by Brian Aker
Second pass of thd cleanup
1317
typedef DECLARE_DRIZZLE_SessionVAR_BASIC(sessionvar_bool_t, bool);
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1318
typedef DECLARE_DRIZZLE_SYSVAR_BASIC(sysvar_str_t, char *);
520.1.22 by Brian Aker
Second pass of thd cleanup
1319
typedef DECLARE_DRIZZLE_SessionVAR_BASIC(sessionvar_str_t, char *);
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1320
1321
typedef DECLARE_DRIZZLE_SYSVAR_TYPELIB(sysvar_enum_t, unsigned long);
520.1.22 by Brian Aker
Second pass of thd cleanup
1322
typedef DECLARE_DRIZZLE_SessionVAR_TYPELIB(sessionvar_enum_t, unsigned long);
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1323
typedef DECLARE_DRIZZLE_SYSVAR_TYPELIB(sysvar_set_t, uint64_t);
520.1.22 by Brian Aker
Second pass of thd cleanup
1324
typedef DECLARE_DRIZZLE_SessionVAR_TYPELIB(sessionvar_set_t, uint64_t);
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1325
1326
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_int_t, int);
1327
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_long_t, long);
1328
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_int64_t_t, int64_t);
1329
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_uint_t, uint);
1330
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_ulong_t, ulong);
1331
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_uint64_t_t, uint64_t);
1332
520.1.22 by Brian Aker
Second pass of thd cleanup
1333
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_int_t, int);
1334
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_long_t, long);
1335
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_int64_t_t, int64_t);
1336
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_uint_t, uint);
1337
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_ulong_t, ulong);
1338
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_uint64_t_t, uint64_t);
1 by brian
clean slate
1339
520.1.22 by Brian Aker
Second pass of thd cleanup
1340
typedef bool *(*mysql_sys_var_ptr_p)(Session* a_session, int offset);
1 by brian
clean slate
1341
1342
1343
/****************************************************************************
1344
  default variable data check and update functions
1345
****************************************************************************/
1346
520.1.22 by Brian Aker
Second pass of thd cleanup
1347
static int check_func_bool(Session *session __attribute__((unused)),
77.1.46 by Monty Taylor
Finished the warnings work!
1348
                           struct st_mysql_sys_var *var,
1 by brian
clean slate
1349
                           void *save, st_mysql_value *value)
1350
{
1351
  char buff[STRING_BUFFER_USUAL_SIZE];
1352
  const char *strvalue= "NULL", *str;
1353
  int result, length;
53.2.2 by Monty Taylor
Updated everything that needs updating to compile with -std=gnu99 -pedantic
1354
  int64_t tmp;
1 by brian
clean slate
1355
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1356
  if (value->value_type(value) == DRIZZLE_VALUE_TYPE_STRING)
1 by brian
clean slate
1357
  {
1358
    length= sizeof(buff);
1359
    if (!(str= value->val_str(value, buff, &length)) ||
1360
        (result= find_type(&bool_typelib, str, length, 1)-1) < 0)
1361
    {
1362
      if (str)
1363
        strvalue= str;
1364
      goto err;
1365
    }
1366
  }
1367
  else
1368
  {
1369
    if (value->val_int(value, &tmp) < 0)
1370
      goto err;
1371
    if (tmp > 1)
1372
    {
1373
      llstr(tmp, buff);
1374
      strvalue= buff;
1375
      goto err;
1376
    }
1377
    result= (int) tmp;
1378
  }
1379
  *(int*)save= -result;
1380
  return 0;
1381
err:
1382
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
1383
  return 1;
1384
}
1385
1386
520.1.22 by Brian Aker
Second pass of thd cleanup
1387
static int check_func_int(Session *session, struct st_mysql_sys_var *var,
1 by brian
clean slate
1388
                          void *save, st_mysql_value *value)
1389
{
143 by Brian Aker
Bool cleanup.
1390
  bool fixed;
53.2.2 by Monty Taylor
Updated everything that needs updating to compile with -std=gnu99 -pedantic
1391
  int64_t tmp;
1 by brian
clean slate
1392
  struct my_option options;
1393
  value->val_int(value, &tmp);
1394
  plugin_opt_set_limits(&options, var);
1395
1396
  if (var->flags & PLUGIN_VAR_UNSIGNED)
482 by Brian Aker
Remove uint.
1397
    *(uint32_t *)save= (uint) getopt_ull_limit_value((uint64_t) tmp, &options,
1 by brian
clean slate
1398
                                                   &fixed);
1399
  else
1400
    *(int *)save= (int) getopt_ll_limit_value(tmp, &options, &fixed);
1401
520.1.22 by Brian Aker
Second pass of thd cleanup
1402
  return throw_bounds_warning(session, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
152 by Brian Aker
longlong replacement
1403
                              var->name, (int64_t) tmp);
1 by brian
clean slate
1404
}
1405
1406
520.1.22 by Brian Aker
Second pass of thd cleanup
1407
static int check_func_long(Session *session, struct st_mysql_sys_var *var,
1 by brian
clean slate
1408
                          void *save, st_mysql_value *value)
1409
{
143 by Brian Aker
Bool cleanup.
1410
  bool fixed;
53.2.2 by Monty Taylor
Updated everything that needs updating to compile with -std=gnu99 -pedantic
1411
  int64_t tmp;
1 by brian
clean slate
1412
  struct my_option options;
1413
  value->val_int(value, &tmp);
1414
  plugin_opt_set_limits(&options, var);
1415
1416
  if (var->flags & PLUGIN_VAR_UNSIGNED)
151 by Brian Aker
Ulonglong to uint64_t
1417
    *(ulong *)save= (ulong) getopt_ull_limit_value((uint64_t) tmp, &options,
1 by brian
clean slate
1418
                                                   &fixed);
1419
  else
1420
    *(long *)save= (long) getopt_ll_limit_value(tmp, &options, &fixed);
1421
520.1.22 by Brian Aker
Second pass of thd cleanup
1422
  return throw_bounds_warning(session, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
152 by Brian Aker
longlong replacement
1423
                              var->name, (int64_t) tmp);
1 by brian
clean slate
1424
}
1425
1426
520.1.22 by Brian Aker
Second pass of thd cleanup
1427
static int check_func_int64_t(Session *session, struct st_mysql_sys_var *var,
1 by brian
clean slate
1428
                               void *save, st_mysql_value *value)
1429
{
143 by Brian Aker
Bool cleanup.
1430
  bool fixed;
53.2.2 by Monty Taylor
Updated everything that needs updating to compile with -std=gnu99 -pedantic
1431
  int64_t tmp;
1 by brian
clean slate
1432
  struct my_option options;
1433
  value->val_int(value, &tmp);
1434
  plugin_opt_set_limits(&options, var);
1435
1436
  if (var->flags & PLUGIN_VAR_UNSIGNED)
151 by Brian Aker
Ulonglong to uint64_t
1437
    *(uint64_t *)save= getopt_ull_limit_value((uint64_t) tmp, &options,
1 by brian
clean slate
1438
                                               &fixed);
1439
  else
152 by Brian Aker
longlong replacement
1440
    *(int64_t *)save= getopt_ll_limit_value(tmp, &options, &fixed);
1 by brian
clean slate
1441
520.1.22 by Brian Aker
Second pass of thd cleanup
1442
  return throw_bounds_warning(session, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
152 by Brian Aker
longlong replacement
1443
                              var->name, (int64_t) tmp);
1 by brian
clean slate
1444
}
1445
520.1.22 by Brian Aker
Second pass of thd cleanup
1446
static int check_func_str(Session *session,
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
1447
                          struct st_mysql_sys_var *var __attribute__((unused)),
1 by brian
clean slate
1448
                          void *save, st_mysql_value *value)
1449
{
1450
  char buff[STRING_BUFFER_USUAL_SIZE];
1451
  const char *str;
1452
  int length;
1453
1454
  length= sizeof(buff);
1455
  if ((str= value->val_str(value, buff, &length)))
520.1.22 by Brian Aker
Second pass of thd cleanup
1456
    str= session->strmake(str, length);
1 by brian
clean slate
1457
  *(const char**)save= str;
1458
  return 0;
1459
}
1460
1461
520.1.22 by Brian Aker
Second pass of thd cleanup
1462
static int check_func_enum(Session *session __attribute__((unused)),
77.1.46 by Monty Taylor
Finished the warnings work!
1463
                           struct st_mysql_sys_var *var,
1 by brian
clean slate
1464
                           void *save, st_mysql_value *value)
1465
{
1466
  char buff[STRING_BUFFER_USUAL_SIZE];
1467
  const char *strvalue= "NULL", *str;
1468
  TYPELIB *typelib;
53.2.2 by Monty Taylor
Updated everything that needs updating to compile with -std=gnu99 -pedantic
1469
  int64_t tmp;
1 by brian
clean slate
1470
  long result;
1471
  int length;
1472
520.1.21 by Brian Aker
THD -> Session rename
1473
  if (var->flags & PLUGIN_VAR_SessionLOCAL)
520.1.22 by Brian Aker
Second pass of thd cleanup
1474
    typelib= ((sessionvar_enum_t*) var)->typelib;
1 by brian
clean slate
1475
  else
1476
    typelib= ((sysvar_enum_t*) var)->typelib;
1477
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1478
  if (value->value_type(value) == DRIZZLE_VALUE_TYPE_STRING)
1 by brian
clean slate
1479
  {
1480
    length= sizeof(buff);
1481
    if (!(str= value->val_str(value, buff, &length)))
1482
      goto err;
1483
    if ((result= (long)find_type(typelib, str, length, 1)-1) < 0)
1484
    {
1485
      strvalue= str;
1486
      goto err;
1487
    }
1488
  }
1489
  else
1490
  {
1491
    if (value->val_int(value, &tmp))
1492
      goto err;
1493
    if (tmp >= typelib->count)
1494
    {
1495
      llstr(tmp, buff);
1496
      strvalue= buff;
1497
      goto err;
1498
    }
1499
    result= (long) tmp;
1500
  }
1501
  *(long*)save= result;
1502
  return 0;
1503
err:
1504
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
1505
  return 1;
1506
}
1507
1508
520.1.22 by Brian Aker
Second pass of thd cleanup
1509
static int check_func_set(Session *session __attribute__((unused)),
77.1.46 by Monty Taylor
Finished the warnings work!
1510
                          struct st_mysql_sys_var *var,
1 by brian
clean slate
1511
                          void *save, st_mysql_value *value)
1512
{
1513
  char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
1514
  const char *strvalue= "NULL", *str;
1515
  TYPELIB *typelib;
151 by Brian Aker
Ulonglong to uint64_t
1516
  uint64_t result;
482 by Brian Aker
Remove uint.
1517
  uint32_t error_len;
1 by brian
clean slate
1518
  bool not_used;
1519
  int length;
1520
520.1.21 by Brian Aker
THD -> Session rename
1521
  if (var->flags & PLUGIN_VAR_SessionLOCAL)
520.1.22 by Brian Aker
Second pass of thd cleanup
1522
    typelib= ((sessionvar_set_t*) var)->typelib;
1 by brian
clean slate
1523
  else
1524
    typelib= ((sysvar_set_t*)var)->typelib;
1525
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1526
  if (value->value_type(value) == DRIZZLE_VALUE_TYPE_STRING)
1 by brian
clean slate
1527
  {
1528
    length= sizeof(buff);
1529
    if (!(str= value->val_str(value, buff, &length)))
1530
      goto err;
1531
    result= find_set(typelib, str, length, NULL,
1532
                     &error, &error_len, &not_used);
1533
    if (error_len)
1534
    {
398.1.4 by Monty Taylor
Renamed max/min.
1535
      strmake(buff, error, cmin(sizeof(buff), (unsigned long)error_len));
1 by brian
clean slate
1536
      strvalue= buff;
1537
      goto err;
1538
    }
1539
  }
1540
  else
1541
  {
53.2.2 by Monty Taylor
Updated everything that needs updating to compile with -std=gnu99 -pedantic
1542
    if (value->val_int(value, (int64_t *)&result))
1 by brian
clean slate
1543
      goto err;
398.1.8 by Monty Taylor
Enabled -Wlong-long.
1544
    if (unlikely((result >= (1UL << typelib->count)) &&
1 by brian
clean slate
1545
                 (typelib->count < sizeof(long)*8)))
1546
    {
1547
      llstr(result, buff);
1548
      strvalue= buff;
1549
      goto err;
1550
    }
1551
  }
151 by Brian Aker
Ulonglong to uint64_t
1552
  *(uint64_t*)save= result;
1 by brian
clean slate
1553
  return 0;
1554
err:
1555
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
1556
  return 1;
1557
}
1558
1559
520.1.22 by Brian Aker
Second pass of thd cleanup
1560
static void update_func_bool(Session *session __attribute__((unused)),
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
1561
                             struct st_mysql_sys_var *var __attribute__((unused)),
1 by brian
clean slate
1562
                             void *tgt, const void *save)
1563
{
199 by Brian Aker
my_bool...
1564
  *(bool *) tgt= *(int *) save ? 1 : 0;
1 by brian
clean slate
1565
}
1566
1567
520.1.22 by Brian Aker
Second pass of thd cleanup
1568
static void update_func_int(Session *session __attribute__((unused)),
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
1569
                            struct st_mysql_sys_var *var __attribute__((unused)),
1 by brian
clean slate
1570
                             void *tgt, const void *save)
1571
{
1572
  *(int *)tgt= *(int *) save;
1573
}
1574
1575
520.1.22 by Brian Aker
Second pass of thd cleanup
1576
static void update_func_long(Session *session __attribute__((unused)),
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
1577
                             struct st_mysql_sys_var *var __attribute__((unused)),
1 by brian
clean slate
1578
                             void *tgt, const void *save)
1579
{
1580
  *(long *)tgt= *(long *) save;
1581
}
1582
1583
520.1.22 by Brian Aker
Second pass of thd cleanup
1584
static void update_func_int64_t(Session *session __attribute__((unused)),
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
1585
                                 struct st_mysql_sys_var *var __attribute__((unused)),
77.1.46 by Monty Taylor
Finished the warnings work!
1586
                                 void *tgt, const void *save)
1 by brian
clean slate
1587
{
152 by Brian Aker
longlong replacement
1588
  *(int64_t *)tgt= *(uint64_t *) save;
1 by brian
clean slate
1589
}
1590
1591
520.1.22 by Brian Aker
Second pass of thd cleanup
1592
static void update_func_str(Session *session __attribute__((unused)), struct st_mysql_sys_var *var,
1 by brian
clean slate
1593
                             void *tgt, const void *save)
1594
{
1595
  char *old= *(char **) tgt;
1596
  *(char **)tgt= *(char **) save;
1597
  if (var->flags & PLUGIN_VAR_MEMALLOC)
1598
  {
1599
    *(char **)tgt= my_strdup(*(char **) save, MYF(0));
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
1600
    free(old);
1 by brian
clean slate
1601
  }
1602
}
1603
1604
1605
/****************************************************************************
1606
  System Variables support
1607
****************************************************************************/
1608
1609
520.1.22 by Brian Aker
Second pass of thd cleanup
1610
sys_var *find_sys_var(Session *session, const char *str, uint32_t length)
1 by brian
clean slate
1611
{
1612
  sys_var *var;
1613
  sys_var_pluginvar *pi= NULL;
1614
  plugin_ref plugin;
1615
1616
  rw_rdlock(&LOCK_system_variables_hash);
1617
  if ((var= intern_find_sys_var(str, length, false)) &&
1618
      (pi= var->cast_pluginvar()))
1619
  {
1620
    rw_unlock(&LOCK_system_variables_hash);
520.1.22 by Brian Aker
Second pass of thd cleanup
1621
    LEX *lex= session ? session->lex : 0;
1 by brian
clean slate
1622
    if (!(plugin= my_intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin))))
1623
      var= NULL; /* failed to lock it, it must be uninstalling */
1624
    else
1625
    if (!(plugin_state(plugin) & PLUGIN_IS_READY))
1626
    {
1627
      /* initialization not completed */
1628
      var= NULL;
1629
      intern_plugin_unlock(lex, plugin);
1630
    }
1631
  }
1632
  else
1633
    rw_unlock(&LOCK_system_variables_hash);
1634
1635
  /*
1636
    If the variable exists but the plugin it is associated with is not ready
1637
    then the intern_plugin_lock did not raise an error, so we do it here.
1638
  */
1639
  if (pi && !var)
1640
    my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1641
  return(var);
1 by brian
clean slate
1642
}
1643
1644
1645
/*
1646
  called by register_var, construct_options and test_plugin_options.
1647
  Returns the 'bookmark' for the named variable.
1648
  LOCK_system_variables_hash should be at least read locked
1649
*/
138 by Brian Aker
Refactoring around sql_plugin.
1650
static st_bookmark *find_bookmark(const char *plugin, const char *name, int flags)
1 by brian
clean slate
1651
{
1652
  st_bookmark *result= NULL;
482 by Brian Aker
Remove uint.
1653
  uint32_t namelen, length, pluginlen= 0;
1 by brian
clean slate
1654
  char *varname, *p;
1655
520.1.21 by Brian Aker
THD -> Session rename
1656
  if (!(flags & PLUGIN_VAR_SessionLOCAL))
1 by brian
clean slate
1657
    return NULL;
1658
1659
  namelen= strlen(name);
1660
  if (plugin)
1661
    pluginlen= strlen(plugin) + 1;
1662
  length= namelen + pluginlen + 2;
1663
  varname= (char*) my_alloca(length);
1664
1665
  if (plugin)
1666
  {
461 by Monty Taylor
Removed NullS. bu-bye.
1667
    strxmov(varname + 1, plugin, "_", name, NULL);
1 by brian
clean slate
1668
    for (p= varname + 1; *p; p++)
1669
      if (*p == '-')
1670
        *p= '_';
1671
  }
1672
  else
1673
    memcpy(varname + 1, name, namelen + 1);
1674
1675
  varname[0]= flags & PLUGIN_VAR_TYPEMASK;
1676
1677
  result= (st_bookmark*) hash_search(&bookmark_hash,
481 by Brian Aker
Remove all of uchar.
1678
                                     (const unsigned char*) varname, length - 1);
1 by brian
clean slate
1679
1680
  my_afree(varname);
1681
  return result;
1682
}
1683
1684
1685
/*
520.1.22 by Brian Aker
Second pass of thd cleanup
1686
  returns a bookmark for session-local variables, creating if neccessary.
1687
  returns null for non session-local variables.
1 by brian
clean slate
1688
  Requires that a write lock is obtained on LOCK_system_variables_hash
1689
*/
1690
static st_bookmark *register_var(const char *plugin, const char *name,
1691
                                 int flags)
1692
{
482 by Brian Aker
Remove uint.
1693
  uint32_t length= strlen(plugin) + strlen(name) + 3, size= 0, offset, new_size;
1 by brian
clean slate
1694
  st_bookmark *result;
1695
  char *varname, *p;
1696
520.1.21 by Brian Aker
THD -> Session rename
1697
  if (!(flags & PLUGIN_VAR_SessionLOCAL))
1 by brian
clean slate
1698
    return NULL;
1699
1700
  switch (flags & PLUGIN_VAR_TYPEMASK) {
1701
  case PLUGIN_VAR_BOOL:
199 by Brian Aker
my_bool...
1702
    size= sizeof(bool);
1 by brian
clean slate
1703
    break;
1704
  case PLUGIN_VAR_INT:
1705
    size= sizeof(int);
1706
    break;
1707
  case PLUGIN_VAR_LONG:
1708
  case PLUGIN_VAR_ENUM:
1709
    size= sizeof(long);
1710
    break;
1711
  case PLUGIN_VAR_LONGLONG:
1712
  case PLUGIN_VAR_SET:
151 by Brian Aker
Ulonglong to uint64_t
1713
    size= sizeof(uint64_t);
1 by brian
clean slate
1714
    break;
1715
  case PLUGIN_VAR_STR:
1716
    size= sizeof(char*);
1717
    break;
1718
  default:
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
1719
    assert(0);
1 by brian
clean slate
1720
    return NULL;
1721
  };
1722
1723
  varname= ((char*) my_alloca(length));
461 by Monty Taylor
Removed NullS. bu-bye.
1724
  strxmov(varname + 1, plugin, "_", name, NULL);
1 by brian
clean slate
1725
  for (p= varname + 1; *p; p++)
1726
    if (*p == '-')
1727
      *p= '_';
1728
1729
  if (!(result= find_bookmark(NULL, varname + 1, flags)))
1730
  {
1731
    result= (st_bookmark*) alloc_root(&plugin_mem_root,
1732
                                      sizeof(struct st_bookmark) + length-1);
1733
    varname[0]= flags & PLUGIN_VAR_TYPEMASK;
1734
    memcpy(result->key, varname, length);
1735
    result->name_len= length - 2;
1736
    result->offset= -1;
1737
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
1738
    assert(size && !(size & (size-1))); /* must be power of 2 */
1 by brian
clean slate
1739
1740
    offset= global_system_variables.dynamic_variables_size;
1741
    offset= (offset + size - 1) & ~(size - 1);
1742
    result->offset= (int) offset;
1743
1744
    new_size= (offset + size + 63) & ~63;
1745
1746
    if (new_size > global_variables_dynamic_size)
1747
    {
1748
      global_system_variables.dynamic_variables_ptr= (char*)
1749
        my_realloc(global_system_variables.dynamic_variables_ptr, new_size,
1750
                   MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
1751
      max_system_variables.dynamic_variables_ptr= (char*)
1752
        my_realloc(max_system_variables.dynamic_variables_ptr, new_size,
1753
                   MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
1754
      /*
1755
        Clear the new variable value space. This is required for string
1756
        variables. If their value is non-NULL, it must point to a valid
1757
        string.
1758
      */
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
1759
      memset(global_system_variables.dynamic_variables_ptr +
1760
             global_variables_dynamic_size, 0,
1761
             new_size - global_variables_dynamic_size);
1762
      memset(max_system_variables.dynamic_variables_ptr +
1763
             global_variables_dynamic_size, 0, 
1764
             new_size - global_variables_dynamic_size);
1 by brian
clean slate
1765
      global_variables_dynamic_size= new_size;
1766
    }
1767
1768
    global_system_variables.dynamic_variables_head= offset;
1769
    max_system_variables.dynamic_variables_head= offset;
1770
    global_system_variables.dynamic_variables_size= offset + size;
1771
    max_system_variables.dynamic_variables_size= offset + size;
1772
    global_system_variables.dynamic_variables_version++;
1773
    max_system_variables.dynamic_variables_version++;
1774
1775
    result->version= global_system_variables.dynamic_variables_version;
1776
1777
    /* this should succeed because we have already checked if a dup exists */
481 by Brian Aker
Remove all of uchar.
1778
    if (my_hash_insert(&bookmark_hash, (unsigned char*) result))
1 by brian
clean slate
1779
    {
1780
      fprintf(stderr, "failed to add placeholder to hash");
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
1781
      assert(0);
1 by brian
clean slate
1782
    }
1783
  }
1784
  my_afree(varname);
1785
  return result;
1786
}
1787
1788
1789
/*
520.1.22 by Brian Aker
Second pass of thd cleanup
1790
  returns a pointer to the memory which holds the session-local variable or
1791
  a pointer to the global variable if session==null.
1 by brian
clean slate
1792
  If required, will sync with global variables if the requested variable
1793
  has not yet been allocated in the current thread.
1794
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
1795
static unsigned char *intern_sys_var_ptr(Session* session, int offset, bool global_lock)
1 by brian
clean slate
1796
{
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
1797
  assert(offset >= 0);
1798
  assert((uint)offset <= global_system_variables.dynamic_variables_head);
1 by brian
clean slate
1799
520.1.22 by Brian Aker
Second pass of thd cleanup
1800
  if (!session)
481 by Brian Aker
Remove all of uchar.
1801
    return (unsigned char*) global_system_variables.dynamic_variables_ptr + offset;
1 by brian
clean slate
1802
1803
  /*
1804
    dynamic_variables_head points to the largest valid offset
1805
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
1806
  if (!session->variables.dynamic_variables_ptr ||
1807
      (uint)offset > session->variables.dynamic_variables_head)
1 by brian
clean slate
1808
  {
482 by Brian Aker
Remove uint.
1809
    uint32_t idx;
1 by brian
clean slate
1810
1811
    rw_rdlock(&LOCK_system_variables_hash);
1812
520.1.22 by Brian Aker
Second pass of thd cleanup
1813
    session->variables.dynamic_variables_ptr= (char*)
1814
      my_realloc(session->variables.dynamic_variables_ptr,
1 by brian
clean slate
1815
                 global_variables_dynamic_size,
1816
                 MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
1817
1818
    if (global_lock)
1819
      pthread_mutex_lock(&LOCK_global_system_variables);
1820
1821
    safe_mutex_assert_owner(&LOCK_global_system_variables);
1822
520.1.22 by Brian Aker
Second pass of thd cleanup
1823
    memcpy(session->variables.dynamic_variables_ptr +
1824
             session->variables.dynamic_variables_size,
1 by brian
clean slate
1825
           global_system_variables.dynamic_variables_ptr +
520.1.22 by Brian Aker
Second pass of thd cleanup
1826
             session->variables.dynamic_variables_size,
1 by brian
clean slate
1827
           global_system_variables.dynamic_variables_size -
520.1.22 by Brian Aker
Second pass of thd cleanup
1828
             session->variables.dynamic_variables_size);
1 by brian
clean slate
1829
1830
    /*
1831
      now we need to iterate through any newly copied 'defaults'
1832
      and if it is a string type with MEMALLOC flag, we need to strdup
1833
    */
1834
    for (idx= 0; idx < bookmark_hash.records; idx++)
1835
    {
1836
      sys_var_pluginvar *pi;
1837
      sys_var *var;
1838
      st_bookmark *v= (st_bookmark*) hash_element(&bookmark_hash,idx);
1839
520.1.22 by Brian Aker
Second pass of thd cleanup
1840
      if (v->version <= session->variables.dynamic_variables_version ||
1 by brian
clean slate
1841
          !(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
1842
          !(pi= var->cast_pluginvar()) ||
1843
          v->key[0] != (pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
1844
        continue;
1845
1846
      /* Here we do anything special that may be required of the data types */
1847
1848
      if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
1849
          pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC)
1850
      {
520.1.22 by Brian Aker
Second pass of thd cleanup
1851
         char **pp= (char**) (session->variables.dynamic_variables_ptr +
1 by brian
clean slate
1852
                             *(int*)(pi->plugin_var + 1));
1853
         if ((*pp= *(char**) (global_system_variables.dynamic_variables_ptr +
1854
                             *(int*)(pi->plugin_var + 1))))
1855
           *pp= my_strdup(*pp, MYF(MY_WME|MY_FAE));
1856
      }
1857
    }
1858
1859
    if (global_lock)
1860
      pthread_mutex_unlock(&LOCK_global_system_variables);
1861
520.1.22 by Brian Aker
Second pass of thd cleanup
1862
    session->variables.dynamic_variables_version=
1 by brian
clean slate
1863
           global_system_variables.dynamic_variables_version;
520.1.22 by Brian Aker
Second pass of thd cleanup
1864
    session->variables.dynamic_variables_head=
1 by brian
clean slate
1865
           global_system_variables.dynamic_variables_head;
520.1.22 by Brian Aker
Second pass of thd cleanup
1866
    session->variables.dynamic_variables_size=
1 by brian
clean slate
1867
           global_system_variables.dynamic_variables_size;
1868
1869
    rw_unlock(&LOCK_system_variables_hash);
1870
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
1871
  return (unsigned char*)session->variables.dynamic_variables_ptr + offset;
1872
}
1873
1874
static bool *mysql_sys_var_ptr_bool(Session* a_session, int offset)
1875
{
1876
  return (bool *)intern_sys_var_ptr(a_session, offset, true);
1877
}
1878
1879
static int *mysql_sys_var_ptr_int(Session* a_session, int offset)
1880
{
1881
  return (int *)intern_sys_var_ptr(a_session, offset, true);
1882
}
1883
1884
static long *mysql_sys_var_ptr_long(Session* a_session, int offset)
1885
{
1886
  return (long *)intern_sys_var_ptr(a_session, offset, true);
1887
}
1888
1889
static int64_t *mysql_sys_var_ptr_int64_t(Session* a_session, int offset)
1890
{
1891
  return (int64_t *)intern_sys_var_ptr(a_session, offset, true);
1892
}
1893
1894
static char **mysql_sys_var_ptr_str(Session* a_session, int offset)
1895
{
1896
  return (char **)intern_sys_var_ptr(a_session, offset, true);
1897
}
1898
1899
static uint64_t *mysql_sys_var_ptr_set(Session* a_session, int offset)
1900
{
1901
  return (uint64_t *)intern_sys_var_ptr(a_session, offset, true);
1902
}
1903
1904
static unsigned long *mysql_sys_var_ptr_enum(Session* a_session, int offset)
1905
{
1906
  return (unsigned long *)intern_sys_var_ptr(a_session, offset, true);
1907
}
1908
1909
1910
void plugin_sessionvar_init(Session *session)
1911
{
1912
  plugin_ref old_table_plugin= session->variables.table_plugin;
1913
  
1914
  session->variables.table_plugin= NULL;
1915
  cleanup_variables(session, &session->variables);
1916
  
1917
  session->variables= global_system_variables;
1918
  session->variables.table_plugin= NULL;
1 by brian
clean slate
1919
1920
  /* we are going to allocate these lazily */
520.1.22 by Brian Aker
Second pass of thd cleanup
1921
  session->variables.dynamic_variables_version= 0;
1922
  session->variables.dynamic_variables_size= 0;
1923
  session->variables.dynamic_variables_ptr= 0;
1 by brian
clean slate
1924
520.1.22 by Brian Aker
Second pass of thd cleanup
1925
  session->variables.table_plugin=
1 by brian
clean slate
1926
        my_intern_plugin_lock(NULL, global_system_variables.table_plugin);
1927
  intern_plugin_unlock(NULL, old_table_plugin);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1928
  return;
1 by brian
clean slate
1929
}
1930
1931
1932
/*
1933
  Unlocks all system variables which hold a reference
1934
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
1935
static void unlock_variables(Session *session __attribute__((unused)),
77.1.46 by Monty Taylor
Finished the warnings work!
1936
                             struct system_variables *vars)
1 by brian
clean slate
1937
{
1938
  intern_plugin_unlock(NULL, vars->table_plugin);
1939
  vars->table_plugin= NULL;
1940
}
1941
1942
1943
/*
1944
  Frees memory used by system variables
1945
1946
  Unlike plugin_vars_free_values() it frees all variables of all plugins,
1947
  it's used on shutdown.
1948
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
1949
static void cleanup_variables(Session *session, struct system_variables *vars)
1 by brian
clean slate
1950
{
1951
  st_bookmark *v;
1952
  sys_var_pluginvar *pivar;
1953
  sys_var *var;
1954
  int flags;
482 by Brian Aker
Remove uint.
1955
  uint32_t idx;
1 by brian
clean slate
1956
1957
  rw_rdlock(&LOCK_system_variables_hash);
1958
  for (idx= 0; idx < bookmark_hash.records; idx++)
1959
  {
1960
    v= (st_bookmark*) hash_element(&bookmark_hash, idx);
1961
    if (v->version > vars->dynamic_variables_version ||
1962
        !(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
1963
        !(pivar= var->cast_pluginvar()) ||
1964
        v->key[0] != (pivar->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
1965
      continue;
1966
1967
    flags= pivar->plugin_var->flags;
1968
1969
    if ((flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
520.1.21 by Brian Aker
THD -> Session rename
1970
        flags & PLUGIN_VAR_SessionLOCAL && flags & PLUGIN_VAR_MEMALLOC)
1 by brian
clean slate
1971
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
1972
      char **ptr= (char**) pivar->real_value_ptr(session, OPT_SESSION);
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
1973
      free(*ptr);
1 by brian
clean slate
1974
      *ptr= NULL;
1975
    }
1976
  }
1977
  rw_unlock(&LOCK_system_variables_hash);
1978
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
1979
  assert(vars->table_plugin == NULL);
1 by brian
clean slate
1980
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
1981
  free(vars->dynamic_variables_ptr);
1 by brian
clean slate
1982
  vars->dynamic_variables_ptr= NULL;
1983
  vars->dynamic_variables_size= 0;
1984
  vars->dynamic_variables_version= 0;
1985
}
1986
1987
520.1.22 by Brian Aker
Second pass of thd cleanup
1988
void plugin_sessionvar_cleanup(Session *session)
1 by brian
clean slate
1989
{
482 by Brian Aker
Remove uint.
1990
  uint32_t idx;
1 by brian
clean slate
1991
  plugin_ref *list;
1992
520.1.22 by Brian Aker
Second pass of thd cleanup
1993
  unlock_variables(session, &session->variables);
1994
  cleanup_variables(session, &session->variables);
1 by brian
clean slate
1995
520.1.22 by Brian Aker
Second pass of thd cleanup
1996
  if ((idx= session->lex->plugins.elements))
1 by brian
clean slate
1997
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
1998
    list= ((plugin_ref*) session->lex->plugins.buffer) + idx - 1;
1999
    while ((unsigned char*) list >= session->lex->plugins.buffer)
1 by brian
clean slate
2000
      intern_plugin_unlock(NULL, *list--);
2001
  }
2002
520.1.22 by Brian Aker
Second pass of thd cleanup
2003
  reset_dynamic(&session->lex->plugins);
1 by brian
clean slate
2004
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2005
  return;
1 by brian
clean slate
2006
}
2007
2008
2009
/**
2010
  @brief Free values of thread variables of a plugin.
2011
2012
  This must be called before a plugin is deleted. Otherwise its
2013
  variables are no longer accessible and the value space is lost. Note
2014
  that only string values with PLUGIN_VAR_MEMALLOC are allocated and
2015
  must be freed.
2016
2017
  @param[in]        vars        Chain of system variables of a plugin
2018
*/
2019
2020
static void plugin_vars_free_values(sys_var *vars)
2021
{
2022
2023
  for (sys_var *var= vars; var; var= var->next)
2024
  {
2025
    sys_var_pluginvar *piv= var->cast_pluginvar();
2026
    if (piv &&
2027
        ((piv->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR) &&
2028
        (piv->plugin_var->flags & PLUGIN_VAR_MEMALLOC))
2029
    {
2030
      /* Free the string from global_system_variables. */
2031
      char **valptr= (char**) piv->real_value_ptr(NULL, OPT_GLOBAL);
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
2032
      free(*valptr);
1 by brian
clean slate
2033
      *valptr= NULL;
2034
    }
2035
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2036
  return;
1 by brian
clean slate
2037
}
2038
2039
2040
bool sys_var_pluginvar::check_update_type(Item_result type)
2041
{
2042
  if (is_readonly())
2043
    return 1;
2044
  switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
2045
  case PLUGIN_VAR_INT:
2046
  case PLUGIN_VAR_LONG:
2047
  case PLUGIN_VAR_LONGLONG:
2048
    return type != INT_RESULT;
2049
  case PLUGIN_VAR_STR:
2050
    return type != STRING_RESULT;
2051
  default:
2052
    return 0;
2053
  }
2054
}
2055
2056
2057
SHOW_TYPE sys_var_pluginvar::show_type()
2058
{
2059
  switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
2060
  case PLUGIN_VAR_BOOL:
2061
    return SHOW_MY_BOOL;
2062
  case PLUGIN_VAR_INT:
2063
    return SHOW_INT;
2064
  case PLUGIN_VAR_LONG:
2065
    return SHOW_LONG;
2066
  case PLUGIN_VAR_LONGLONG:
2067
    return SHOW_LONGLONG;
2068
  case PLUGIN_VAR_STR:
2069
    return SHOW_CHAR_PTR;
2070
  case PLUGIN_VAR_ENUM:
2071
  case PLUGIN_VAR_SET:
2072
    return SHOW_CHAR;
2073
  default:
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
2074
    assert(0);
1 by brian
clean slate
2075
    return SHOW_UNDEF;
2076
  }
2077
}
2078
2079
520.1.22 by Brian Aker
Second pass of thd cleanup
2080
unsigned char* sys_var_pluginvar::real_value_ptr(Session *session, enum_var_type type)
1 by brian
clean slate
2081
{
520.1.22 by Brian Aker
Second pass of thd cleanup
2082
  assert(session || (type == OPT_GLOBAL));
520.1.21 by Brian Aker
THD -> Session rename
2083
  if (plugin_var->flags & PLUGIN_VAR_SessionLOCAL)
1 by brian
clean slate
2084
  {
2085
    if (type == OPT_GLOBAL)
520.1.22 by Brian Aker
Second pass of thd cleanup
2086
      session= NULL;
1 by brian
clean slate
2087
520.1.22 by Brian Aker
Second pass of thd cleanup
2088
    return intern_sys_var_ptr(session, *(int*) (plugin_var+1), false);
1 by brian
clean slate
2089
  }
481 by Brian Aker
Remove all of uchar.
2090
  return *(unsigned char**) (plugin_var+1);
1 by brian
clean slate
2091
}
2092
2093
2094
TYPELIB* sys_var_pluginvar::plugin_var_typelib(void)
2095
{
520.1.21 by Brian Aker
THD -> Session rename
2096
  switch (plugin_var->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_SessionLOCAL)) {
1 by brian
clean slate
2097
  case PLUGIN_VAR_ENUM:
2098
    return ((sysvar_enum_t *)plugin_var)->typelib;
2099
  case PLUGIN_VAR_SET:
2100
    return ((sysvar_set_t *)plugin_var)->typelib;
520.1.21 by Brian Aker
THD -> Session rename
2101
  case PLUGIN_VAR_ENUM | PLUGIN_VAR_SessionLOCAL:
520.1.22 by Brian Aker
Second pass of thd cleanup
2102
    return ((sessionvar_enum_t *)plugin_var)->typelib;
520.1.21 by Brian Aker
THD -> Session rename
2103
  case PLUGIN_VAR_SET | PLUGIN_VAR_SessionLOCAL:
520.1.22 by Brian Aker
Second pass of thd cleanup
2104
    return ((sessionvar_set_t *)plugin_var)->typelib;
1 by brian
clean slate
2105
  default:
2106
    return NULL;
2107
  }
2108
  return NULL;
2109
}
2110
2111
520.1.22 by Brian Aker
Second pass of thd cleanup
2112
unsigned char* sys_var_pluginvar::value_ptr(Session *session, enum_var_type type,
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
2113
                                    LEX_STRING *base __attribute__((unused)))
1 by brian
clean slate
2114
{
481 by Brian Aker
Remove all of uchar.
2115
  unsigned char* result;
1 by brian
clean slate
2116
520.1.22 by Brian Aker
Second pass of thd cleanup
2117
  result= real_value_ptr(session, type);
1 by brian
clean slate
2118
2119
  if ((plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_ENUM)
481 by Brian Aker
Remove all of uchar.
2120
    result= (unsigned char*) get_type(plugin_var_typelib(), *(ulong*)result);
1 by brian
clean slate
2121
  else if ((plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_SET)
2122
  {
2123
    char buffer[STRING_BUFFER_USUAL_SIZE];
2124
    String str(buffer, sizeof(buffer), system_charset_info);
2125
    TYPELIB *typelib= plugin_var_typelib();
151 by Brian Aker
Ulonglong to uint64_t
2126
    uint64_t mask= 1, value= *(uint64_t*) result;
482 by Brian Aker
Remove uint.
2127
    uint32_t i;
1 by brian
clean slate
2128
2129
    str.length(0);
2130
    for (i= 0; i < typelib->count; i++, mask<<=1)
2131
    {
2132
      if (!(value & mask))
2133
        continue;
2134
      str.append(typelib->type_names[i], typelib->type_lengths[i]);
2135
      str.append(',');
2136
    }
2137
481 by Brian Aker
Remove all of uchar.
2138
    result= (unsigned char*) "";
1 by brian
clean slate
2139
    if (str.length())
520.1.22 by Brian Aker
Second pass of thd cleanup
2140
      result= (unsigned char*) session->strmake(str.ptr(), str.length()-1);
1 by brian
clean slate
2141
  }
2142
  return result;
2143
}
2144
2145
520.1.22 by Brian Aker
Second pass of thd cleanup
2146
bool sys_var_pluginvar::check(Session *session, set_var *var)
1 by brian
clean slate
2147
{
2148
  st_item_value_holder value;
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
2149
  assert(is_readonly() || plugin_var->check);
1 by brian
clean slate
2150
2151
  value.value_type= item_value_type;
2152
  value.val_str= item_val_str;
2153
  value.val_int= item_val_int;
2154
  value.val_real= item_val_real;
2155
  value.item= var->value;
2156
2157
  return is_readonly() ||
520.1.22 by Brian Aker
Second pass of thd cleanup
2158
         plugin_var->check(session, plugin_var, &var->save_result, &value);
1 by brian
clean slate
2159
}
2160
2161
520.1.22 by Brian Aker
Second pass of thd cleanup
2162
void sys_var_pluginvar::set_default(Session *session, enum_var_type type)
1 by brian
clean slate
2163
{
2164
  const void *src;
2165
  void *tgt;
2166
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
2167
  assert(is_readonly() || plugin_var->update);
1 by brian
clean slate
2168
2169
  if (is_readonly())
2170
    return;
2171
2172
  pthread_mutex_lock(&LOCK_global_system_variables);
520.1.22 by Brian Aker
Second pass of thd cleanup
2173
  tgt= real_value_ptr(session, type);
1 by brian
clean slate
2174
  src= ((void **) (plugin_var + 1) + 1);
2175
520.1.21 by Brian Aker
THD -> Session rename
2176
  if (plugin_var->flags & PLUGIN_VAR_SessionLOCAL)
1 by brian
clean slate
2177
  {
2178
    if (type != OPT_GLOBAL)
520.1.22 by Brian Aker
Second pass of thd cleanup
2179
      src= real_value_ptr(session, OPT_GLOBAL);
1 by brian
clean slate
2180
    else
2181
    switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
2182
	case PLUGIN_VAR_INT:
520.1.22 by Brian Aker
Second pass of thd cleanup
2183
	  src= &((sessionvar_uint_t*) plugin_var)->def_val;
1 by brian
clean slate
2184
	  break;
2185
	case PLUGIN_VAR_LONG:
520.1.22 by Brian Aker
Second pass of thd cleanup
2186
	  src= &((sessionvar_ulong_t*) plugin_var)->def_val;
1 by brian
clean slate
2187
	  break;
2188
	case PLUGIN_VAR_LONGLONG:
520.1.22 by Brian Aker
Second pass of thd cleanup
2189
	  src= &((sessionvar_uint64_t_t*) plugin_var)->def_val;
1 by brian
clean slate
2190
	  break;
2191
	case PLUGIN_VAR_ENUM:
520.1.22 by Brian Aker
Second pass of thd cleanup
2192
	  src= &((sessionvar_enum_t*) plugin_var)->def_val;
1 by brian
clean slate
2193
	  break;
2194
	case PLUGIN_VAR_SET:
520.1.22 by Brian Aker
Second pass of thd cleanup
2195
	  src= &((sessionvar_set_t*) plugin_var)->def_val;
1 by brian
clean slate
2196
	  break;
2197
	case PLUGIN_VAR_BOOL:
520.1.22 by Brian Aker
Second pass of thd cleanup
2198
	  src= &((sessionvar_bool_t*) plugin_var)->def_val;
1 by brian
clean slate
2199
	  break;
2200
	case PLUGIN_VAR_STR:
520.1.22 by Brian Aker
Second pass of thd cleanup
2201
	  src= &((sessionvar_str_t*) plugin_var)->def_val;
1 by brian
clean slate
2202
	  break;
2203
	default:
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
2204
	  assert(0);
1 by brian
clean slate
2205
	}
2206
  }
2207
520.1.22 by Brian Aker
Second pass of thd cleanup
2208
  /* session must equal current_session if PLUGIN_VAR_SessionLOCAL flag is set */
520.1.21 by Brian Aker
THD -> Session rename
2209
  assert(!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) ||
520.1.22 by Brian Aker
Second pass of thd cleanup
2210
              session == current_session);
1 by brian
clean slate
2211
520.1.21 by Brian Aker
THD -> Session rename
2212
  if (!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) || type == OPT_GLOBAL)
1 by brian
clean slate
2213
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
2214
    plugin_var->update(session, plugin_var, tgt, src);
1 by brian
clean slate
2215
    pthread_mutex_unlock(&LOCK_global_system_variables);
2216
  }
2217
  else
2218
  {
2219
    pthread_mutex_unlock(&LOCK_global_system_variables);
520.1.22 by Brian Aker
Second pass of thd cleanup
2220
    plugin_var->update(session, plugin_var, tgt, src);
1 by brian
clean slate
2221
  }
2222
}
2223
2224
520.1.22 by Brian Aker
Second pass of thd cleanup
2225
bool sys_var_pluginvar::update(Session *session, set_var *var)
1 by brian
clean slate
2226
{
2227
  void *tgt;
2228
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
2229
  assert(is_readonly() || plugin_var->update);
1 by brian
clean slate
2230
520.1.22 by Brian Aker
Second pass of thd cleanup
2231
  /* session must equal current_session if PLUGIN_VAR_SessionLOCAL flag is set */
520.1.21 by Brian Aker
THD -> Session rename
2232
  assert(!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) ||
520.1.22 by Brian Aker
Second pass of thd cleanup
2233
              session == current_session);
1 by brian
clean slate
2234
2235
  if (is_readonly())
2236
    return 1;
2237
2238
  pthread_mutex_lock(&LOCK_global_system_variables);
520.1.22 by Brian Aker
Second pass of thd cleanup
2239
  tgt= real_value_ptr(session, var->type);
1 by brian
clean slate
2240
520.1.21 by Brian Aker
THD -> Session rename
2241
  if (!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) || var->type == OPT_GLOBAL)
1 by brian
clean slate
2242
  {
2243
    /* variable we are updating has global scope, so we unlock after updating */
520.1.22 by Brian Aker
Second pass of thd cleanup
2244
    plugin_var->update(session, plugin_var, tgt, &var->save_result);
1 by brian
clean slate
2245
    pthread_mutex_unlock(&LOCK_global_system_variables);
2246
  }
2247
  else
2248
  {
2249
    pthread_mutex_unlock(&LOCK_global_system_variables);
520.1.22 by Brian Aker
Second pass of thd cleanup
2250
    plugin_var->update(session, plugin_var, tgt, &var->save_result);
1 by brian
clean slate
2251
  }
2252
 return 0;
2253
}
2254
2255
2256
#define OPTION_SET_LIMITS(type, options, opt) \
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
2257
  options->var_type= type;                    \
2258
  options->def_value= (opt)->def_val;         \
2259
  options->min_value= (opt)->min_val;         \
2260
  options->max_value= (opt)->max_val;         \
1 by brian
clean slate
2261
  options->block_size= (long) (opt)->blk_sz
2262
2263
2264
static void plugin_opt_set_limits(struct my_option *options,
2265
                                  const struct st_mysql_sys_var *opt)
2266
{
2267
  options->sub_size= 0;
2268
2269
  switch (opt->flags & (PLUGIN_VAR_TYPEMASK |
520.1.21 by Brian Aker
THD -> Session rename
2270
                        PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL)) {
1 by brian
clean slate
2271
  /* global system variables */
2272
  case PLUGIN_VAR_INT:
2273
    OPTION_SET_LIMITS(GET_INT, options, (sysvar_int_t*) opt);
2274
    break;
2275
  case PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED:
2276
    OPTION_SET_LIMITS(GET_UINT, options, (sysvar_uint_t*) opt);
2277
    break;
2278
  case PLUGIN_VAR_LONG:
2279
    OPTION_SET_LIMITS(GET_LONG, options, (sysvar_long_t*) opt);
2280
    break;
2281
  case PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED:
2282
    OPTION_SET_LIMITS(GET_ULONG, options, (sysvar_ulong_t*) opt);
2283
    break;
2284
  case PLUGIN_VAR_LONGLONG:
152 by Brian Aker
longlong replacement
2285
    OPTION_SET_LIMITS(GET_LL, options, (sysvar_int64_t_t*) opt);
1 by brian
clean slate
2286
    break;
2287
  case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED:
151 by Brian Aker
Ulonglong to uint64_t
2288
    OPTION_SET_LIMITS(GET_ULL, options, (sysvar_uint64_t_t*) opt);
1 by brian
clean slate
2289
    break;
2290
  case PLUGIN_VAR_ENUM:
2291
    options->var_type= GET_ENUM;
2292
    options->typelib= ((sysvar_enum_t*) opt)->typelib;
2293
    options->def_value= ((sysvar_enum_t*) opt)->def_val;
2294
    options->min_value= options->block_size= 0;
2295
    options->max_value= options->typelib->count - 1;
2296
    break;
2297
  case PLUGIN_VAR_SET:
2298
    options->var_type= GET_SET;
2299
    options->typelib= ((sysvar_set_t*) opt)->typelib;
2300
    options->def_value= ((sysvar_set_t*) opt)->def_val;
2301
    options->min_value= options->block_size= 0;
398.1.8 by Monty Taylor
Enabled -Wlong-long.
2302
    options->max_value= (1UL << options->typelib->count) - 1;
1 by brian
clean slate
2303
    break;
2304
  case PLUGIN_VAR_BOOL:
2305
    options->var_type= GET_BOOL;
2306
    options->def_value= ((sysvar_bool_t*) opt)->def_val;
2307
    break;
2308
  case PLUGIN_VAR_STR:
2309
    options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ?
2310
                        GET_STR_ALLOC : GET_STR);
157 by Brian Aker
Second pass cleanup on removal of my_uint types
2311
    options->def_value= (intptr_t) ((sysvar_str_t*) opt)->def_val;
1 by brian
clean slate
2312
    break;
2313
  /* threadlocal variables */
520.1.21 by Brian Aker
THD -> Session rename
2314
  case PLUGIN_VAR_INT | PLUGIN_VAR_SessionLOCAL:
520.1.22 by Brian Aker
Second pass of thd cleanup
2315
    OPTION_SET_LIMITS(GET_INT, options, (sessionvar_int_t*) opt);
1 by brian
clean slate
2316
    break;
520.1.21 by Brian Aker
THD -> Session rename
2317
  case PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
520.1.22 by Brian Aker
Second pass of thd cleanup
2318
    OPTION_SET_LIMITS(GET_UINT, options, (sessionvar_uint_t*) opt);
1 by brian
clean slate
2319
    break;
520.1.21 by Brian Aker
THD -> Session rename
2320
  case PLUGIN_VAR_LONG | PLUGIN_VAR_SessionLOCAL:
520.1.22 by Brian Aker
Second pass of thd cleanup
2321
    OPTION_SET_LIMITS(GET_LONG, options, (sessionvar_long_t*) opt);
1 by brian
clean slate
2322
    break;
520.1.21 by Brian Aker
THD -> Session rename
2323
  case PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
520.1.22 by Brian Aker
Second pass of thd cleanup
2324
    OPTION_SET_LIMITS(GET_ULONG, options, (sessionvar_ulong_t*) opt);
1 by brian
clean slate
2325
    break;
520.1.21 by Brian Aker
THD -> Session rename
2326
  case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_SessionLOCAL:
520.1.22 by Brian Aker
Second pass of thd cleanup
2327
    OPTION_SET_LIMITS(GET_LL, options, (sessionvar_int64_t_t*) opt);
1 by brian
clean slate
2328
    break;
520.1.21 by Brian Aker
THD -> Session rename
2329
  case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
520.1.22 by Brian Aker
Second pass of thd cleanup
2330
    OPTION_SET_LIMITS(GET_ULL, options, (sessionvar_uint64_t_t*) opt);
1 by brian
clean slate
2331
    break;
520.1.21 by Brian Aker
THD -> Session rename
2332
  case PLUGIN_VAR_ENUM | PLUGIN_VAR_SessionLOCAL:
1 by brian
clean slate
2333
    options->var_type= GET_ENUM;
520.1.22 by Brian Aker
Second pass of thd cleanup
2334
    options->typelib= ((sessionvar_enum_t*) opt)->typelib;
2335
    options->def_value= ((sessionvar_enum_t*) opt)->def_val;
1 by brian
clean slate
2336
    options->min_value= options->block_size= 0;
2337
    options->max_value= options->typelib->count - 1;
2338
    break;
520.1.21 by Brian Aker
THD -> Session rename
2339
  case PLUGIN_VAR_SET | PLUGIN_VAR_SessionLOCAL:
1 by brian
clean slate
2340
    options->var_type= GET_SET;
520.1.22 by Brian Aker
Second pass of thd cleanup
2341
    options->typelib= ((sessionvar_set_t*) opt)->typelib;
2342
    options->def_value= ((sessionvar_set_t*) opt)->def_val;
1 by brian
clean slate
2343
    options->min_value= options->block_size= 0;
398.1.8 by Monty Taylor
Enabled -Wlong-long.
2344
    options->max_value= (1UL << options->typelib->count) - 1;
1 by brian
clean slate
2345
    break;
520.1.21 by Brian Aker
THD -> Session rename
2346
  case PLUGIN_VAR_BOOL | PLUGIN_VAR_SessionLOCAL:
1 by brian
clean slate
2347
    options->var_type= GET_BOOL;
520.1.22 by Brian Aker
Second pass of thd cleanup
2348
    options->def_value= ((sessionvar_bool_t*) opt)->def_val;
1 by brian
clean slate
2349
    break;
520.1.21 by Brian Aker
THD -> Session rename
2350
  case PLUGIN_VAR_STR | PLUGIN_VAR_SessionLOCAL:
1 by brian
clean slate
2351
    options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ?
2352
                        GET_STR_ALLOC : GET_STR);
520.1.22 by Brian Aker
Second pass of thd cleanup
2353
    options->def_value= (intptr_t) ((sessionvar_str_t*) opt)->def_val;
1 by brian
clean slate
2354
    break;
2355
  default:
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
2356
    assert(0);
1 by brian
clean slate
2357
  }
2358
  options->arg_type= REQUIRED_ARG;
2359
  if (opt->flags & PLUGIN_VAR_NOCMDARG)
2360
    options->arg_type= NO_ARG;
2361
  if (opt->flags & PLUGIN_VAR_OPCMDARG)
2362
    options->arg_type= OPT_ARG;
2363
}
2364
143 by Brian Aker
Bool cleanup.
2365
extern "C" bool get_one_plugin_option(int optid, const struct my_option *,
1 by brian
clean slate
2366
                                         char *);
2367
143 by Brian Aker
Bool cleanup.
2368
bool get_one_plugin_option(int optid __attribute__((unused)),
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
2369
                              const struct my_option *opt __attribute__((unused)),
2370
                              char *argument __attribute__((unused)))
1 by brian
clean slate
2371
{
2372
  return 0;
2373
}
2374
2375
2376
static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
138 by Brian Aker
Refactoring around sql_plugin.
2377
                             my_option *options, bool can_disable)
1 by brian
clean slate
2378
{
2379
  const char *plugin_name= tmp->plugin->name;
482 by Brian Aker
Remove uint.
2380
  uint32_t namelen= strlen(plugin_name), optnamelen;
2381
  uint32_t buffer_length= namelen * 4 + (can_disable ? 75 : 10);
1 by brian
clean slate
2382
  char *name= (char*) alloc_root(mem_root, buffer_length) + 1;
2383
  char *optname, *p;
2384
  int index= 0, offset= 0;
2385
  st_mysql_sys_var *opt, **plugin_option;
2386
  st_bookmark *v;
2387
2388
  /* support --skip-plugin-foo syntax */
2389
  memcpy(name, plugin_name, namelen + 1);
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
2390
  my_casedn_str(&my_charset_utf8_general_ci, name);
461 by Monty Taylor
Removed NullS. bu-bye.
2391
  strxmov(name + namelen + 1, "plugin-", name, NULL);
1 by brian
clean slate
2392
  /* Now we have namelen + 1 + 7 + namelen + 1 == namelen * 2 + 9. */
2393
2394
  for (p= name + namelen*2 + 8; p > name; p--)
2395
    if (*p == '_')
2396
      *p= '-';
2397
2398
  if (can_disable)
2399
  {
2400
    strxmov(name + namelen*2 + 10, "Enable ", plugin_name, " plugin. "
461 by Monty Taylor
Removed NullS. bu-bye.
2401
            "Disable with --skip-", name," (will save memory).", NULL);
1 by brian
clean slate
2402
    /*
2403
      Now we have namelen * 2 + 10 (one char unused) + 7 + namelen + 9 +
2404
      20 + namelen + 20 + 1 == namelen * 4 + 67.
2405
    */
2406
2407
    options[0].comment= name + namelen*2 + 10;
2408
  }
2409
2410
  options[1].name= (options[0].name= name) + namelen + 1;
2411
  options[0].id= options[1].id= 256; /* must be >255. dup id ok */
2412
  options[0].var_type= options[1].var_type= GET_BOOL;
2413
  options[0].arg_type= options[1].arg_type= NO_ARG;
138 by Brian Aker
Refactoring around sql_plugin.
2414
  options[0].def_value= options[1].def_value= true;
1 by brian
clean slate
2415
  options[0].value= options[0].u_max_value=
77.1.78 by Monty Taylor
One last bunch of warnings edits.
2416
  options[1].value= options[1].u_max_value= (char**) (name - 1);
1 by brian
clean slate
2417
  options+= 2;
2418
2419
  /*
2420
    Two passes as the 2nd pass will take pointer addresses for use
2421
    by my_getopt and register_var() in the first pass uses realloc
2422
  */
2423
2424
  for (plugin_option= tmp->plugin->system_vars;
2425
       plugin_option && *plugin_option; plugin_option++, index++)
2426
  {
2427
    opt= *plugin_option;
520.1.21 by Brian Aker
THD -> Session rename
2428
    if (!(opt->flags & PLUGIN_VAR_SessionLOCAL))
1 by brian
clean slate
2429
      continue;
2430
    if (!(register_var(name, opt->name, opt->flags)))
2431
      continue;
2432
    switch (opt->flags & PLUGIN_VAR_TYPEMASK) {
2433
    case PLUGIN_VAR_BOOL:
520.1.22 by Brian Aker
Second pass of thd cleanup
2434
      (((sessionvar_bool_t *)opt)->resolve)= mysql_sys_var_ptr_bool;
1 by brian
clean slate
2435
      break;
2436
    case PLUGIN_VAR_INT:
520.1.22 by Brian Aker
Second pass of thd cleanup
2437
      (((sessionvar_int_t *)opt)->resolve)= mysql_sys_var_ptr_int;
1 by brian
clean slate
2438
      break;
2439
    case PLUGIN_VAR_LONG:
520.1.22 by Brian Aker
Second pass of thd cleanup
2440
      (((sessionvar_long_t *)opt)->resolve)= mysql_sys_var_ptr_long;
1 by brian
clean slate
2441
      break;
2442
    case PLUGIN_VAR_LONGLONG:
520.1.22 by Brian Aker
Second pass of thd cleanup
2443
      (((sessionvar_int64_t_t *)opt)->resolve)= mysql_sys_var_ptr_int64_t;
1 by brian
clean slate
2444
      break;
2445
    case PLUGIN_VAR_STR:
520.1.22 by Brian Aker
Second pass of thd cleanup
2446
      (((sessionvar_str_t *)opt)->resolve)= mysql_sys_var_ptr_str;
1 by brian
clean slate
2447
      break;
2448
    case PLUGIN_VAR_ENUM:
520.1.22 by Brian Aker
Second pass of thd cleanup
2449
      (((sessionvar_enum_t *)opt)->resolve)= mysql_sys_var_ptr_enum;
1 by brian
clean slate
2450
      break;
2451
    case PLUGIN_VAR_SET:
520.1.22 by Brian Aker
Second pass of thd cleanup
2452
      (((sessionvar_set_t *)opt)->resolve)= mysql_sys_var_ptr_set;
1 by brian
clean slate
2453
      break;
2454
    default:
338 by Monty Taylor
Tagged more strings.
2455
      sql_print_error(_("Unknown variable type code 0x%x in plugin '%s'."),
1 by brian
clean slate
2456
                      opt->flags, plugin_name);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2457
      return(-1);
1 by brian
clean slate
2458
    };
2459
  }
2460
2461
  for (plugin_option= tmp->plugin->system_vars;
2462
       plugin_option && *plugin_option; plugin_option++, index++)
2463
  {
2464
    switch ((opt= *plugin_option)->flags & PLUGIN_VAR_TYPEMASK) {
2465
    case PLUGIN_VAR_BOOL:
2466
      if (!opt->check)
2467
        opt->check= check_func_bool;
2468
      if (!opt->update)
2469
        opt->update= update_func_bool;
2470
      break;
2471
    case PLUGIN_VAR_INT:
2472
      if (!opt->check)
2473
        opt->check= check_func_int;
2474
      if (!opt->update)
2475
        opt->update= update_func_int;
2476
      break;
2477
    case PLUGIN_VAR_LONG:
2478
      if (!opt->check)
2479
        opt->check= check_func_long;
2480
      if (!opt->update)
2481
        opt->update= update_func_long;
2482
      break;
2483
    case PLUGIN_VAR_LONGLONG:
2484
      if (!opt->check)
152 by Brian Aker
longlong replacement
2485
        opt->check= check_func_int64_t;
1 by brian
clean slate
2486
      if (!opt->update)
152 by Brian Aker
longlong replacement
2487
        opt->update= update_func_int64_t;
1 by brian
clean slate
2488
      break;
2489
    case PLUGIN_VAR_STR:
2490
      if (!opt->check)
2491
        opt->check= check_func_str;
2492
      if (!opt->update)
2493
      {
2494
        opt->update= update_func_str;
9 by Brian Aker
Warnings cleanup
2495
        if ((opt->flags & (PLUGIN_VAR_MEMALLOC | PLUGIN_VAR_READONLY)) == false)
1 by brian
clean slate
2496
        {
2497
          opt->flags|= PLUGIN_VAR_READONLY;
338 by Monty Taylor
Tagged more strings.
2498
          sql_print_warning(_("Server variable %s of plugin %s was forced "
1 by brian
clean slate
2499
                            "to be read-only: string variable without "
338 by Monty Taylor
Tagged more strings.
2500
                            "update_func and PLUGIN_VAR_MEMALLOC flag"),
1 by brian
clean slate
2501
                            opt->name, plugin_name);
2502
        }
2503
      }
2504
      break;
2505
    case PLUGIN_VAR_ENUM:
2506
      if (!opt->check)
2507
        opt->check= check_func_enum;
2508
      if (!opt->update)
2509
        opt->update= update_func_long;
2510
      break;
2511
    case PLUGIN_VAR_SET:
2512
      if (!opt->check)
2513
        opt->check= check_func_set;
2514
      if (!opt->update)
152 by Brian Aker
longlong replacement
2515
        opt->update= update_func_int64_t;
1 by brian
clean slate
2516
      break;
2517
    default:
338 by Monty Taylor
Tagged more strings.
2518
      sql_print_error(_("Unknown variable type code 0x%x in plugin '%s'."),
1 by brian
clean slate
2519
                      opt->flags, plugin_name);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2520
      return(-1);
1 by brian
clean slate
2521
    }
2522
520.1.21 by Brian Aker
THD -> Session rename
2523
    if ((opt->flags & (PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_SessionLOCAL))
1 by brian
clean slate
2524
                    == PLUGIN_VAR_NOCMDOPT)
2525
      continue;
2526
2527
    if (!opt->name)
2528
    {
338 by Monty Taylor
Tagged more strings.
2529
      sql_print_error(_("Missing variable name in plugin '%s'."),
1 by brian
clean slate
2530
                      plugin_name);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2531
      return(-1);
1 by brian
clean slate
2532
    }
2533
520.1.21 by Brian Aker
THD -> Session rename
2534
    if (!(opt->flags & PLUGIN_VAR_SessionLOCAL))
1 by brian
clean slate
2535
    {
2536
      optnamelen= strlen(opt->name);
2537
      optname= (char*) alloc_root(mem_root, namelen + optnamelen + 2);
461 by Monty Taylor
Removed NullS. bu-bye.
2538
      strxmov(optname, name, "-", opt->name, NULL);
1 by brian
clean slate
2539
      optnamelen= namelen + optnamelen + 1;
2540
    }
2541
    else
2542
    {
2543
      /* this should not fail because register_var should create entry */
2544
      if (!(v= find_bookmark(name, opt->name, opt->flags)))
2545
      {
338 by Monty Taylor
Tagged more strings.
2546
        sql_print_error(_("Thread local variable '%s' not allocated "
2547
                        "in plugin '%s'."), opt->name, plugin_name);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2548
        return(-1);
1 by brian
clean slate
2549
      }
2550
2551
      *(int*)(opt + 1)= offset= v->offset;
2552
2553
      if (opt->flags & PLUGIN_VAR_NOCMDOPT)
2554
        continue;
2555
2556
      optname= (char*) memdup_root(mem_root, v->key + 1, 
2557
                                   (optnamelen= v->name_len) + 1);
2558
    }
2559
2560
    /* convert '_' to '-' */
2561
    for (p= optname; *p; p++)
2562
      if (*p == '_')
2563
        *p= '-';
2564
2565
    options->name= optname;
2566
    options->comment= opt->comment;
2567
    options->app_type= opt;
2568
    options->id= (options-1)->id + 1;
2569
2570
    plugin_opt_set_limits(options, opt);
2571
520.1.21 by Brian Aker
THD -> Session rename
2572
    if (opt->flags & PLUGIN_VAR_SessionLOCAL)
77.1.78 by Monty Taylor
One last bunch of warnings edits.
2573
      options->value= options->u_max_value= (char**)
1 by brian
clean slate
2574
        (global_system_variables.dynamic_variables_ptr + offset);
2575
    else
77.1.78 by Monty Taylor
One last bunch of warnings edits.
2576
      options->value= options->u_max_value= *(char***) (opt + 1);
1 by brian
clean slate
2577
2578
    options[1]= options[0];
2579
    options[1].name= p= (char*) alloc_root(mem_root, optnamelen + 8);
2580
    options[1].comment= 0; // hidden
461 by Monty Taylor
Removed NullS. bu-bye.
2581
    strxmov(p, "plugin-", optname, NULL);
1 by brian
clean slate
2582
2583
    options+= 2;
2584
  }
2585
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2586
  return(0);
1 by brian
clean slate
2587
}
2588
2589
2590
static my_option *construct_help_options(MEM_ROOT *mem_root,
2591
                                         struct st_plugin_int *p)
2592
{
2593
  st_mysql_sys_var **opt;
2594
  my_option *opts;
138 by Brian Aker
Refactoring around sql_plugin.
2595
  bool can_disable;
482 by Brian Aker
Remove uint.
2596
  uint32_t count= EXTRA_OPTIONS;
1 by brian
clean slate
2597
9 by Brian Aker
Warnings cleanup
2598
  for (opt= p->plugin->system_vars; opt && *opt; opt++, count+= 2) {};
1 by brian
clean slate
2599
2600
  if (!(opts= (my_option*) alloc_root(mem_root, sizeof(my_option) * count)))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2601
    return(NULL);
1 by brian
clean slate
2602
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
2603
  memset(opts, 0, sizeof(my_option) * count);
1 by brian
clean slate
2604
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
2605
  if ((my_strcasecmp(&my_charset_utf8_general_ci, p->name.str, "MyISAM") == 0))
138 by Brian Aker
Refactoring around sql_plugin.
2606
    can_disable= false;
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
2607
  else if ((my_strcasecmp(&my_charset_utf8_general_ci, p->name.str, "MEMORY") == 0))
138 by Brian Aker
Refactoring around sql_plugin.
2608
    can_disable= false;
2609
  else
2610
    can_disable= true;
2611
2612
2613
  if (construct_options(mem_root, p, opts, can_disable))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2614
    return(NULL);
1 by brian
clean slate
2615
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2616
  return(opts);
1 by brian
clean slate
2617
}
2618
2619
2620
/*
2621
  SYNOPSIS
2622
    test_plugin_options()
2623
    tmp_root                    temporary scratch space
2624
    plugin                      internal plugin structure
2625
    argc                        user supplied arguments
2626
    argv                        user supplied arguments
2627
    default_enabled             default plugin enable status
2628
  RETURNS:
2629
    0 SUCCESS - plugin should be enabled/loaded
2630
  NOTE:
2631
    Requires that a write-lock is held on LOCK_system_variables_hash
2632
*/
2633
static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
135 by Brian Aker
Random cleanup. Dead partition tests, pass operator in sql_plugin, mtr based
2634
                               int *argc, char **argv)
1 by brian
clean slate
2635
{
2636
  struct sys_var_chain chain= { NULL, NULL };
138 by Brian Aker
Refactoring around sql_plugin.
2637
  bool enabled_saved= true;
2638
  bool can_disable;
1 by brian
clean slate
2639
  MEM_ROOT *mem_root= alloc_root_inited(&tmp->mem_root) ?
2640
                      &tmp->mem_root : &plugin_mem_root;
2641
  st_mysql_sys_var **opt;
2642
  my_option *opts= NULL;
2643
  char *p, *varname;
2644
  int error;
2645
  st_mysql_sys_var *o;
2646
  sys_var *v;
2647
  struct st_bookmark *var;
482 by Brian Aker
Remove uint.
2648
  uint32_t len, count= EXTRA_OPTIONS;
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
2649
  assert(tmp->plugin && tmp->name.str);
1 by brian
clean slate
2650
2651
  for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
2652
    count+= 2; /* --{plugin}-{optname} and --plugin-{plugin}-{optname} */
2653
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
2654
  if ((my_strcasecmp(&my_charset_utf8_general_ci, tmp->name.str, "MyISAM") == 0))
138 by Brian Aker
Refactoring around sql_plugin.
2655
    can_disable= false;
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
2656
  else if ((my_strcasecmp(&my_charset_utf8_general_ci, tmp->name.str, "MEMORY") == 0))
138 by Brian Aker
Refactoring around sql_plugin.
2657
    can_disable= false;
2658
  else
2659
    can_disable= true;
1 by brian
clean slate
2660
2661
  if (count > EXTRA_OPTIONS || (*argc > 1))
2662
  {
2663
    if (!(opts= (my_option*) alloc_root(tmp_root, sizeof(my_option) * count)))
2664
    {
338 by Monty Taylor
Tagged more strings.
2665
      sql_print_error(_("Out of memory for plugin '%s'."), tmp->name.str);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2666
      return(-1);
1 by brian
clean slate
2667
    }
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
2668
    memset(opts, 0, sizeof(my_option) * count);
1 by brian
clean slate
2669
138 by Brian Aker
Refactoring around sql_plugin.
2670
    if (construct_options(tmp_root, tmp, opts, can_disable))
1 by brian
clean slate
2671
    {
338 by Monty Taylor
Tagged more strings.
2672
      sql_print_error(_("Bad options for plugin '%s'."), tmp->name.str);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2673
      return(-1);
1 by brian
clean slate
2674
    }
2675
2676
    error= handle_options(argc, &argv, opts, get_one_plugin_option);
2677
    (*argc)++; /* add back one for the program name */
2678
2679
    if (error)
2680
    {
338 by Monty Taylor
Tagged more strings.
2681
       sql_print_error(_("Parsing options for plugin '%s' failed."),
1 by brian
clean slate
2682
                       tmp->name.str);
2683
       goto err;
2684
    }
2685
  }
2686
2687
  error= 1;
2688
2689
  {
2690
    for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
2691
    {
2692
      if (((o= *opt)->flags & PLUGIN_VAR_NOSYSVAR))
2693
        continue;
2694
2695
      if ((var= find_bookmark(tmp->name.str, o->name, o->flags)))
2696
        v= new (mem_root) sys_var_pluginvar(var->key + 1, o);
2697
      else
2698
      {
2699
        len= tmp->name.length + strlen(o->name) + 2;
2700
        varname= (char*) alloc_root(mem_root, len);
461 by Monty Taylor
Removed NullS. bu-bye.
2701
        strxmov(varname, tmp->name.str, "-", o->name, NULL);
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
2702
        my_casedn_str(&my_charset_utf8_general_ci, varname);
1 by brian
clean slate
2703
2704
        for (p= varname; *p; p++)
2705
          if (*p == '-')
2706
            *p= '_';
2707
2708
        v= new (mem_root) sys_var_pluginvar(varname, o);
2709
      }
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
2710
      assert(v); /* check that an object was actually constructed */
1 by brian
clean slate
2711
2712
      /*
2713
        Add to the chain of variables.
2714
        Done like this for easier debugging so that the
2715
        pointer to v is not lost on optimized builds.
2716
      */
2717
      v->chain_sys_var(&chain);
2718
    }
2719
    if (chain.first)
2720
    {
2721
      chain.last->next = NULL;
2722
      if (mysql_add_sys_var_chain(chain.first, NULL))
2723
      {
338 by Monty Taylor
Tagged more strings.
2724
        sql_print_error(_("Plugin '%s' has conflicting system variables"),
1 by brian
clean slate
2725
                        tmp->name.str);
2726
        goto err;
2727
      }
2728
      tmp->system_vars= chain.first;
2729
    }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2730
    return(0);
1 by brian
clean slate
2731
  }
2732
2733
  if (enabled_saved && global_system_variables.log_warnings)
338 by Monty Taylor
Tagged more strings.
2734
    sql_print_information(_("Plugin '%s' disabled by command line option"),
1 by brian
clean slate
2735
                          tmp->name.str);
2736
err:
2737
  if (opts)
2738
    my_cleanup_options(opts);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2739
  return(error);
1 by brian
clean slate
2740
}
2741
2742
2743
/****************************************************************************
2744
  Help Verbose text with Plugin System Variables
2745
****************************************************************************/
2746
2747
static int option_cmp(my_option *a, my_option *b)
2748
{
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
2749
  return my_strcasecmp(&my_charset_utf8_general_ci, a->name, b->name);
1 by brian
clean slate
2750
}
2751
2752
482 by Brian Aker
Remove uint.
2753
void my_print_help_inc_plugins(my_option *main_options, uint32_t size)
1 by brian
clean slate
2754
{
2755
  DYNAMIC_ARRAY all_options;
2756
  struct st_plugin_int *p;
2757
  MEM_ROOT mem_root;
2758
  my_option *opt;
2759
2760
  init_alloc_root(&mem_root, 4096, 4096);
2761
  my_init_dynamic_array(&all_options, sizeof(my_option), size, size/4);
2762
2763
  if (initialized)
482 by Brian Aker
Remove uint.
2764
    for (uint32_t idx= 0; idx < plugin_array.elements; idx++)
1 by brian
clean slate
2765
    {
2766
      p= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
2767
2768
      if (!p->plugin->system_vars ||
2769
          !(opt= construct_help_options(&mem_root, p)))
2770
        continue;
2771
2772
      /* Only options with a non-NULL comment are displayed in help text */
2773
      for (;opt->id; opt++)
2774
        if (opt->comment)
481 by Brian Aker
Remove all of uchar.
2775
          insert_dynamic(&all_options, (unsigned char*) opt);
1 by brian
clean slate
2776
    }
2777
2778
  for (;main_options->id; main_options++)
481 by Brian Aker
Remove all of uchar.
2779
    insert_dynamic(&all_options, (unsigned char*) main_options);
1 by brian
clean slate
2780
2781
  sort_dynamic(&all_options, (qsort_cmp) option_cmp);
2782
2783
  /* main_options now points to the empty option terminator */
481 by Brian Aker
Remove all of uchar.
2784
  insert_dynamic(&all_options, (unsigned char*) main_options);
1 by brian
clean slate
2785
2786
  my_print_help((my_option*) all_options.buffer);
2787
  my_print_variables((my_option*) all_options.buffer);
2788
2789
  delete_dynamic(&all_options);
2790
  free_root(&mem_root, MYF(0));
2791
}
2792