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