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