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