~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/qcache.h>
971.3.15 by Eric Day
Added protocol init/final to plugin type structs.
24
#include <drizzled/protocol.h>
520.8.2 by Monty Taylor
Moved sql_parse.h and sql_error.h out of common_includes.
25
#include <drizzled/sql_parse.h>
549 by Monty Taylor
Took gettext.h out of header files.
26
#include <drizzled/scheduling.h>
971.1.48 by Monty Taylor
Quick fix.
27
#include <drizzled/transaction_services.h>
575.4.7 by Monty Taylor
More header cleanup.
28
#include <drizzled/show.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
29
#include <drizzled/handler.h>
30
#include <drizzled/set_var.h>
31
#include <drizzled/session.h>
642.1.20 by Lee
header file clean up
32
#include <drizzled/item/null.h>
908.1.10 by Monty Taylor
It sure is drizzled/plugin_registry.cc - not drizzled/plugin_registry.c.
33
#include <drizzled/plugin_registry.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
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
45
using namespace std;
992.1.39 by Monty Taylor
Removed the m4-based plugin system.
46
 
47
typedef struct drizzled_plugin_manifest builtin_plugin[];
48
extern builtin_plugin DRIZZLED_BUILTIN_LIST;
49
static drizzled_plugin_manifest *drizzled_builtins[]=
50
{
51
  DRIZZLED_BUILTIN_LIST,(struct drizzled_plugin_manifest *)0
52
};
1 by brian
clean slate
53
54
char *opt_plugin_load= NULL;
992.1.22 by Monty Taylor
Moved towards having register_plugins.py make builtin plugins, so we can have a first step.
55
const char *opt_plugin_load_default= QUOTE_ARG(DRIZZLED_PLUGIN_LIST);
1 by brian
clean slate
56
char *opt_plugin_dir_ptr;
57
char opt_plugin_dir[FN_REFLEN];
58
static const char *plugin_declarations_sym= "_mysql_plugin_declarations_";
59
60
/* Note that 'int version' must be the first field of every plugin
61
   sub-structure (plugin->info).
62
*/
63
962.1.6 by Brian Aker
Cut down on shutdown loop of plugins (cutting stuff out in order to simplify
64
static bool initialized= false;
1 by brian
clean slate
65
66
static DYNAMIC_ARRAY plugin_dl_array;
67
static DYNAMIC_ARRAY plugin_array;
908.2.1 by Monty Taylor
First pass at refactoring plugins - factored out sql_map.
68
1 by brian
clean slate
69
static bool reap_needed= false;
70
71
/*
72
  write-lock on LOCK_system_variables_hash is required before modifying
73
  the following variables/structures
74
*/
75
static MEM_ROOT plugin_mem_root;
482 by Brian Aker
Remove uint.
76
static uint32_t global_variables_dynamic_size= 0;
1 by brian
clean slate
77
static HASH bookmark_hash;
78
79
80
/*
81
  hidden part of opaque value passed to variable check functions.
82
  Used to provide a object-like structure to non C++ consumers.
83
*/
84
struct st_item_value_holder : public st_mysql_value
85
{
86
  Item *item;
87
};
88
89
90
/*
91
  stored in bookmark_hash, this structure is never removed from the
520.1.22 by Brian Aker
Second pass of thd cleanup
92
  hash and is used to mark a single offset for a session local variable
1 by brian
clean slate
93
  even if plugins have been uninstalled and reinstalled, repeatedly.
94
  This structure is allocated from plugin_mem_root.
95
96
  The key format is as follows:
97
    1 byte         - variable type code
98
    name_len bytes - variable name
99
    '\0'           - end of key
100
*/
101
struct st_bookmark
102
{
482 by Brian Aker
Remove uint.
103
  uint32_t name_len;
1 by brian
clean slate
104
  int offset;
482 by Brian Aker
Remove uint.
105
  uint32_t version;
1 by brian
clean slate
106
  char key[1];
107
};
108
109
110
/*
111
  skeleton of a plugin variable - portion of structure common to all.
112
*/
113
struct st_mysql_sys_var
114
{
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
115
  DRIZZLE_PLUGIN_VAR_HEADER;
1 by brian
clean slate
116
};
117
118
119
/*
120
  sys_var class for access to all plugin variables visible to the user
121
*/
122
class sys_var_pluginvar: public sys_var
123
{
124
public:
125
  struct st_plugin_int *plugin;
126
  struct st_mysql_sys_var *plugin_var;
127
128
  static void *operator new(size_t size, MEM_ROOT *mem_root)
895 by Brian Aker
Completion (?) of uint conversion.
129
  { return (void*) alloc_root(mem_root, (uint32_t) size); }
654 by Brian Aker
Remove unused (yet more)
130
  static void operator delete(void *, size_t)
1 by brian
clean slate
131
  { TRASH(ptr_arg, size); }
132
133
  sys_var_pluginvar(const char *name_arg,
134
                    struct st_mysql_sys_var *plugin_var_arg)
135
    :sys_var(name_arg), plugin_var(plugin_var_arg) {}
136
  sys_var_pluginvar *cast_pluginvar() { return this; }
137
  bool is_readonly() const { return plugin_var->flags & PLUGIN_VAR_READONLY; }
138
  bool check_type(enum_var_type type)
520.1.21 by Brian Aker
THD -> Session rename
139
  { return !(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) && type != OPT_GLOBAL; }
1 by brian
clean slate
140
  bool check_update_type(Item_result type);
141
  SHOW_TYPE show_type();
520.1.22 by Brian Aker
Second pass of thd cleanup
142
  unsigned char* real_value_ptr(Session *session, enum_var_type type);
1 by brian
clean slate
143
  TYPELIB* plugin_var_typelib(void);
779.3.10 by Monty Taylor
Turned on -Wshadow.
144
  unsigned char* value_ptr(Session *session, enum_var_type type,
145
                           const LEX_STRING *base);
520.1.22 by Brian Aker
Second pass of thd cleanup
146
  bool check(Session *session, set_var *var);
654 by Brian Aker
Remove unused (yet more)
147
  bool check_default(enum_var_type)
77.1.46 by Monty Taylor
Finished the warnings work!
148
    { return is_readonly(); }
654 by Brian Aker
Remove unused (yet more)
149
  void set_default(Session *session, enum_var_type);
520.1.22 by Brian Aker
Second pass of thd cleanup
150
  bool update(Session *session, set_var *var);
1 by brian
clean slate
151
};
152
153
154
/* prototypes */
155
static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
156
                             const char *list);
157
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
158
                               int *, char **);
971.1.54 by Monty Taylor
Trimmed out some plugin type stuff.
159
static bool register_builtin(struct st_plugin_int *,
1 by brian
clean slate
160
                             struct st_plugin_int **);
520.1.22 by Brian Aker
Second pass of thd cleanup
161
static void unlock_variables(Session *session, struct system_variables *vars);
162
static void cleanup_variables(Session *session, struct system_variables *vars);
1 by brian
clean slate
163
static void plugin_vars_free_values(sys_var *vars);
164
static void plugin_opt_set_limits(struct my_option *options,
165
                                  const struct st_mysql_sys_var *opt);
166
static void reap_plugins(void);
167
168
169
/* declared in set_var.cc */
482 by Brian Aker
Remove uint.
170
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
171
extern bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
152 by Brian Aker
longlong replacement
172
                                 const char *name, int64_t val);
1 by brian
clean slate
173
174
/****************************************************************************
175
  Value type thunks, allows the C world to play in the C++ world
176
****************************************************************************/
177
178
static int item_value_type(struct st_mysql_value *value)
179
{
180
  switch (((st_item_value_holder*)value)->item->result_type()) {
181
  case INT_RESULT:
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
182
    return DRIZZLE_VALUE_TYPE_INT;
1 by brian
clean slate
183
  case REAL_RESULT:
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
184
    return DRIZZLE_VALUE_TYPE_REAL;
1 by brian
clean slate
185
  default:
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
186
    return DRIZZLE_VALUE_TYPE_STRING;
1 by brian
clean slate
187
  }
188
}
189
190
static const char *item_val_str(struct st_mysql_value *value,
191
                                char *buffer, int *length)
192
{
193
  String str(buffer, *length, system_charset_info), *res;
194
  if (!(res= ((st_item_value_holder*)value)->item->val_str(&str)))
195
    return NULL;
196
  *length= res->length();
197
  if (res->c_ptr_quick() == buffer)
198
    return buffer;
199
200
  /*
201
    Lets be nice and create a temporary string since the
202
    buffer was too small
203
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
204
  return current_session->strmake(res->c_ptr_quick(), res->length());
1 by brian
clean slate
205
}
206
207
53.2.2 by Monty Taylor
Updated everything that needs updating to compile with -std=gnu99 -pedantic
208
static int item_val_int(struct st_mysql_value *value, int64_t *buf)
1 by brian
clean slate
209
{
210
  Item *item= ((st_item_value_holder*)value)->item;
211
  *buf= item->val_int();
212
  if (item->is_null())
213
    return 1;
214
  return 0;
215
}
216
217
218
static int item_val_real(struct st_mysql_value *value, double *buf)
219
{
220
  Item *item= ((st_item_value_holder*)value)->item;
221
  *buf= item->val_real();
222
  if (item->is_null())
223
    return 1;
224
  return 0;
225
}
226
227
228
/****************************************************************************
229
  Plugin support code
230
****************************************************************************/
231
232
static struct st_plugin_dl *plugin_dl_find(const LEX_STRING *dl)
233
{
482 by Brian Aker
Remove uint.
234
  uint32_t i;
1 by brian
clean slate
235
  struct st_plugin_dl *tmp;
681 by Brian Aker
Style cleanup
236
1 by brian
clean slate
237
  for (i= 0; i < plugin_dl_array.elements; i++)
238
  {
239
    tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
962.1.5 by Brian Aker
Remove ref_count from DLL plugin.
240
    if (! my_strnncoll(files_charset_info,
481 by Brian Aker
Remove all of uchar.
241
                       (const unsigned char *)dl->str, dl->length,
242
                       (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
243
      return(tmp);
1 by brian
clean slate
244
  }
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
245
  return(0);
1 by brian
clean slate
246
}
247
248
static st_plugin_dl *plugin_dl_insert_or_reuse(struct st_plugin_dl *plugin_dl)
249
{
482 by Brian Aker
Remove uint.
250
  uint32_t i;
1 by brian
clean slate
251
  struct st_plugin_dl *tmp;
681 by Brian Aker
Style cleanup
252
1 by brian
clean slate
253
  for (i= 0; i < plugin_dl_array.elements; i++)
254
  {
255
    tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
256
    {
257
      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
258
      return(tmp);
1 by brian
clean slate
259
    }
260
  }
481 by Brian Aker
Remove all of uchar.
261
  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
262
    return(0);
1 by brian
clean slate
263
  tmp= *dynamic_element(&plugin_dl_array, plugin_dl_array.elements - 1,
264
                        struct st_plugin_dl **)=
481 by Brian Aker
Remove all of uchar.
265
      (struct st_plugin_dl *) memdup_root(&plugin_mem_root, (unsigned char*)plugin_dl,
1 by brian
clean slate
266
                                           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
267
  return(tmp);
1 by brian
clean slate
268
}
269
270
static inline void free_plugin_mem(struct st_plugin_dl *p)
271
{
272
  if (p->handle)
273
    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.
274
  free(p->dl.str);
1 by brian
clean slate
275
}
276
277
278
static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
279
{
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
280
  string dlpath;
281
  uint32_t plugin_dir_len, dummy_errors;
1 by brian
clean slate
282
  struct st_plugin_dl *tmp, plugin_dl;
283
  void *sym;
284
  plugin_dir_len= strlen(opt_plugin_dir);
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
285
  dlpath.reserve(FN_REFLEN);
1 by brian
clean slate
286
  /*
287
    Ensure that the dll doesn't have a path.
288
    This is done to ensure that only approved libraries from the
289
    plugin directory are used (to make this even remotely secure).
290
  */
266.1.26 by Monty Taylor
Removed my_strchr.
291
  if (strchr(dl->str, FN_LIBCHAR) ||
1 by brian
clean slate
292
      check_string_char_length((LEX_STRING *) dl, "", NAME_CHAR_LEN,
293
                               system_charset_info, 1) ||
294
      plugin_dir_len + dl->length + 1 >= FN_REFLEN)
295
  {
296
    if (report & REPORT_TO_USER)
297
      my_error(ER_UDF_NO_PATHS, MYF(0));
298
    if (report & REPORT_TO_LOG)
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
299
      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
300
    return(0);
1 by brian
clean slate
301
  }
302
  /* If this dll is already loaded just increase ref_count. */
303
  if ((tmp= plugin_dl_find(dl)))
304
  {
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
305
    return(tmp);
1 by brian
clean slate
306
  }
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
307
  memset(&plugin_dl, 0, sizeof(plugin_dl));
1 by brian
clean slate
308
  /* Compile dll path */
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
309
  dlpath.append(opt_plugin_dir);
310
  dlpath.append("/");
311
  dlpath.append(dl->str);
1 by brian
clean slate
312
  /* Open new dll handle */
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
313
  if (!(plugin_dl.handle= dlopen(dlpath.c_str(), RTLD_LAZY|RTLD_GLOBAL)))
1 by brian
clean slate
314
  {
315
    const char *errmsg=dlerror();
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
316
    uint32_t dlpathlen= dlpath.length();
317
    if (!dlpath.compare(0, dlpathlen, errmsg))
1 by brian
clean slate
318
    { // if errmsg starts from dlpath, trim this prefix.
319
      errmsg+=dlpathlen;
320
      if (*errmsg == ':') errmsg++;
321
      if (*errmsg == ' ') errmsg++;
322
    }
323
    if (report & REPORT_TO_USER)
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
324
      my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath.c_str(), errno, errmsg);
1 by brian
clean slate
325
    if (report & REPORT_TO_LOG)
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
326
      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
327
    return(0);
1 by brian
clean slate
328
  }
177.4.1 by mark
remove some useless version checking code from sql_plugin.cc
329
1 by brian
clean slate
330
  /* Find plugin declarations */
331
  if (!(sym= dlsym(plugin_dl.handle, plugin_declarations_sym)))
332
  {
333
    free_plugin_mem(&plugin_dl);
334
    if (report & REPORT_TO_USER)
335
      my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_declarations_sym);
336
    if (report & REPORT_TO_LOG)
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
337
      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
338
    return(0);
1 by brian
clean slate
339
  }
340
971.1.59 by Monty Taylor
Renamed st_mysql_plugin to drizzled_plugin_manifest.
341
  plugin_dl.plugins= (struct drizzled_plugin_manifest *)sym;
1 by brian
clean slate
342
343
  /* Duplicate and convert dll name */
344
  plugin_dl.dl.length= dl->length * files_charset_info->mbmaxlen + 1;
641.3.8 by Monty Taylor
Removed my_malloc from drizzled.
345
  if (! (plugin_dl.dl.str= (char*) malloc(plugin_dl.dl.length)))
1 by brian
clean slate
346
  {
347
    free_plugin_mem(&plugin_dl);
348
    if (report & REPORT_TO_USER)
349
      my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length);
350
    if (report & REPORT_TO_LOG)
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
351
      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
352
    return(0);
1 by brian
clean slate
353
  }
354
  plugin_dl.dl.length= copy_and_convert(plugin_dl.dl.str, plugin_dl.dl.length,
355
    files_charset_info, dl->str, dl->length, system_charset_info,
356
    &dummy_errors);
357
  plugin_dl.dl.str[plugin_dl.dl.length]= 0;
358
  /* Add this dll to array */
359
  if (! (tmp= plugin_dl_insert_or_reuse(&plugin_dl)))
360
  {
361
    free_plugin_mem(&plugin_dl);
362
    if (report & REPORT_TO_USER)
363
      my_error(ER_OUTOFMEMORY, MYF(0), sizeof(struct st_plugin_dl));
364
    if (report & REPORT_TO_LOG)
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
365
      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
366
    return(0);
1 by brian
clean slate
367
  }
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
368
  return(tmp);
1 by brian
clean slate
369
}
370
371
372
static void plugin_dl_del(const LEX_STRING *dl)
373
{
482 by Brian Aker
Remove uint.
374
  uint32_t i;
1 by brian
clean slate
375
376
  for (i= 0; i < plugin_dl_array.elements; i++)
377
  {
378
    struct st_plugin_dl *tmp= *dynamic_element(&plugin_dl_array, i,
379
                                               struct st_plugin_dl **);
962.1.5 by Brian Aker
Remove ref_count from DLL plugin.
380
    if (! my_strnncoll(files_charset_info,
481 by Brian Aker
Remove all of uchar.
381
                       (const unsigned char *)dl->str, dl->length,
382
                       (const unsigned char *)tmp->dl.str, tmp->dl.length))
1 by brian
clean slate
383
    {
384
      /* Do not remove this element, unless no other plugin uses this dll. */
385
      {
386
        free_plugin_mem(tmp);
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
387
        memset(tmp, 0, sizeof(struct st_plugin_dl));
1 by brian
clean slate
388
      }
389
      break;
390
    }
391
  }
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
392
  return;
1 by brian
clean slate
393
}
394
395
396
397
static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin)
398
{
399
  struct st_plugin_int *tmp;
481 by Brian Aker
Remove all of uchar.
400
  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
401
    return(0);
1 by brian
clean slate
402
  tmp= *dynamic_element(&plugin_array, plugin_array.elements - 1,
403
                        struct st_plugin_int **)=
481 by Brian Aker
Remove all of uchar.
404
       (struct st_plugin_int *) memdup_root(&plugin_mem_root, (unsigned char*)plugin,
1 by brian
clean slate
405
                                            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
406
  return(tmp);
1 by brian
clean slate
407
}
408
409
410
/*
411
  NOTE
412
    Requires that a write-lock is held on LOCK_system_variables_hash
413
*/
414
static bool plugin_add(MEM_ROOT *tmp_root,
415
                       const LEX_STRING *name, const LEX_STRING *dl,
416
                       int *argc, char **argv, int report)
417
{
971.1.52 by Monty Taylor
Did the finalizers. Renamed plugin_registry.
418
  PluginRegistry &registry= PluginRegistry::getPluginRegistry();
908.2.1 by Monty Taylor
First pass at refactoring plugins - factored out sql_map.
419
1 by brian
clean slate
420
  struct st_plugin_int tmp;
971.1.59 by Monty Taylor
Renamed st_mysql_plugin to drizzled_plugin_manifest.
421
  struct drizzled_plugin_manifest *plugin;
908.2.1 by Monty Taylor
First pass at refactoring plugins - factored out sql_map.
422
  if (! initialized)
423
    return(0);
424
971.1.54 by Monty Taylor
Trimmed out some plugin type stuff.
425
  if (registry.find(name))
1 by brian
clean slate
426
  {
427
    if (report & REPORT_TO_USER)
428
      my_error(ER_UDF_EXISTS, MYF(0), name->str);
429
    if (report & REPORT_TO_LOG)
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
430
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UDF_EXISTS), name->str);
163 by Brian Aker
Merge Monty's code.
431
    return(true);
1 by brian
clean slate
432
  }
433
  /* 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().
434
  memset(&tmp, 0, sizeof(tmp));
1 by brian
clean slate
435
  if (! (tmp.plugin_dl= plugin_dl_add(dl, report)))
163 by Brian Aker
Merge Monty's code.
436
    return(true);
1 by brian
clean slate
437
  /* Find plugin by name */
177.4.3 by mark
ripped out more plugin ABI and API version checking, and plugin versions are now strings
438
  for (plugin= tmp.plugin_dl->plugins; plugin->name; plugin++)
1 by brian
clean slate
439
  {
482 by Brian Aker
Remove uint.
440
    uint32_t name_len= strlen(plugin->name);
971.1.55 by Monty Taylor
Removed now meaningless plugin_type.
441
    if (! my_strnncoll(system_charset_info,
481 by Brian Aker
Remove all of uchar.
442
                       (const unsigned char *)name->str, name->length,
443
                       (const unsigned char *)plugin->name,
1 by brian
clean slate
444
                       name_len))
445
    {
446
      struct st_plugin_int *tmp_plugin_ptr;
177.4.1 by mark
remove some useless version checking code from sql_plugin.cc
447
1 by brian
clean slate
448
      tmp.plugin= plugin;
449
      tmp.name.str= (char *)plugin->name;
450
      tmp.name.length= name_len;
965.1.1 by Brian Aker
Refactor plugin loading to remove mask (one step closer to getting rid of
451
      tmp.isInited= false;
135 by Brian Aker
Random cleanup. Dead partition tests, pass operator in sql_plugin, mtr based
452
      if (!test_plugin_options(tmp_root, &tmp, argc, argv))
1 by brian
clean slate
453
      {
454
        if ((tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
455
        {
971.1.54 by Monty Taylor
Trimmed out some plugin type stuff.
456
          registry.add(tmp_plugin_ptr);
873.2.21 by Monty Taylor
Removed the HASH for plugin_hash.
457
          init_alloc_root(&tmp_plugin_ptr->mem_root, 4096, 4096);
458
          return(false);
1 by brian
clean slate
459
        }
460
        mysql_del_sys_var_chain(tmp.system_vars);
461
        goto err;
462
      }
463
      /* plugin was disabled */
464
      plugin_dl_del(dl);
163 by Brian Aker
Merge Monty's code.
465
      return(false);
1 by brian
clean slate
466
    }
467
  }
468
  if (report & REPORT_TO_USER)
469
    my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), name->str);
470
  if (report & REPORT_TO_LOG)
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
471
    errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_CANT_FIND_DL_ENTRY), name->str);
1 by brian
clean slate
472
err:
473
  plugin_dl_del(dl);
163 by Brian Aker
Merge Monty's code.
474
  return(true);
1 by brian
clean slate
475
}
476
477
478
static void plugin_del(struct st_plugin_int *plugin)
479
{
971.1.52 by Monty Taylor
Did the finalizers. Renamed plugin_registry.
480
  PluginRegistry &registry= PluginRegistry::getPluginRegistry();
965.1.1 by Brian Aker
Refactor plugin loading to remove mask (one step closer to getting rid of
481
  if (plugin->isInited)
482
  {
483
    if (plugin->plugin->status_vars)
484
    {
485
      remove_status_vars(plugin->plugin->status_vars);
486
    }
487
971.1.52 by Monty Taylor
Did the finalizers. Renamed plugin_registry.
488
    if (plugin->plugin->deinit)
489
      plugin->plugin->deinit(registry);
965.1.1 by Brian Aker
Refactor plugin loading to remove mask (one step closer to getting rid of
490
  }
491
1 by brian
clean slate
492
  /* Free allocated strings before deleting the plugin. */
493
  plugin_vars_free_values(plugin->system_vars);
494
  if (plugin->plugin_dl)
495
    plugin_dl_del(&plugin->plugin_dl->dl);
965.1.1 by Brian Aker
Refactor plugin loading to remove mask (one step closer to getting rid of
496
  plugin->isInited= false;
658 by Brian Aker
Part removal of my_pthread.h
497
  pthread_rwlock_wrlock(&LOCK_system_variables_hash);
1 by brian
clean slate
498
  mysql_del_sys_var_chain(plugin->system_vars);
658 by Brian Aker
Part removal of my_pthread.h
499
  pthread_rwlock_unlock(&LOCK_system_variables_hash);
1 by brian
clean slate
500
  free_root(&plugin->mem_root, MYF(0));
501
}
502
503
static void reap_plugins(void)
504
{
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
505
  size_t count;
506
  uint32_t idx;
507
  struct st_plugin_int *plugin;
660.1.6 by Eric Herman
trailing whitespace fixup
508
1 by brian
clean slate
509
  count= plugin_array.elements;
510
511
  for (idx= 0; idx < count; idx++)
512
  {
513
    plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
514
    plugin_del(plugin);
688 by Brian Aker
Second pass through memory allocation issues (this solves the ones around
515
  }
1 by brian
clean slate
516
}
517
965.1.1 by Brian Aker
Refactor plugin loading to remove mask (one step closer to getting rid of
518
static bool plugin_initialize(struct st_plugin_int *plugin)
1 by brian
clean slate
519
{
965.1.1 by Brian Aker
Refactor plugin loading to remove mask (one step closer to getting rid of
520
  assert(plugin->isInited == false);
1 by brian
clean slate
521
971.1.52 by Monty Taylor
Did the finalizers. Renamed plugin_registry.
522
  PluginRegistry &registry= PluginRegistry::getPluginRegistry();
971.1.51 by Monty Taylor
New-style plugin registration now works.
523
  if (plugin->plugin->init)
524
  {
525
    if (plugin->plugin->init(registry))
526
    {
527
      errmsg_printf(ERRMSG_LVL_ERROR,
528
                    _("Plugin '%s' init function returned error."),
529
                    plugin->name.str);
1 by brian
clean slate
530
      goto err;
531
    }
532
  }
965.1.1 by Brian Aker
Refactor plugin loading to remove mask (one step closer to getting rid of
533
  plugin->isInited= true;
1 by brian
clean slate
534
535
  if (plugin->plugin->status_vars)
536
  {
537
    add_status_vars(plugin->plugin->status_vars); // add_status_vars makes a copy
538
  }
539
540
  /*
541
    set the plugin attribute of plugin's sys vars so they are pointing
542
    to the active plugin
543
  */
544
  if (plugin->system_vars)
545
  {
546
    sys_var_pluginvar *var= plugin->system_vars->cast_pluginvar();
547
    for (;;)
548
    {
549
      var->plugin= plugin;
550
      if (!var->next)
551
        break;
552
      var= var->next->cast_pluginvar();
553
    }
554
  }
555
965.1.1 by Brian Aker
Refactor plugin loading to remove mask (one step closer to getting rid of
556
  return false;
1 by brian
clean slate
557
err:
965.1.1 by Brian Aker
Refactor plugin loading to remove mask (one step closer to getting rid of
558
  return true;
1 by brian
clean slate
559
}
560
561
481 by Brian Aker
Remove all of uchar.
562
extern "C" unsigned char *get_bookmark_hash_key(const unsigned char *, size_t *, bool);
563
564
654 by Brian Aker
Remove unused (yet more)
565
unsigned char *get_bookmark_hash_key(const unsigned char *buff, size_t *length, bool)
1 by brian
clean slate
566
{
567
  struct st_bookmark *var= (st_bookmark *)buff;
568
  *length= var->name_len + 1;
481 by Brian Aker
Remove all of uchar.
569
  return (unsigned char*) var->key;
1 by brian
clean slate
570
}
571
572
573
/*
574
  The logic is that we first load and initialize all compiled in plugins.
575
  From there we load up the dynamic types (assuming we have not been told to
576
  skip this part).
577
578
  Finally we initialize everything, aka the dynamic that have yet to initialize.
579
*/
580
int plugin_init(int *argc, char **argv, int flags)
581
{
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
582
  uint32_t idx;
971.1.59 by Monty Taylor
Renamed st_mysql_plugin to drizzled_plugin_manifest.
583
  struct drizzled_plugin_manifest **builtins;
584
  struct drizzled_plugin_manifest *plugin;
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
585
  struct st_plugin_int tmp, *plugin_ptr;
1 by brian
clean slate
586
  MEM_ROOT tmp_root;
587
588
  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
589
    return(0);
1 by brian
clean slate
590
591
  init_alloc_root(&plugin_mem_root, 4096, 4096);
592
  init_alloc_root(&tmp_root, 4096, 4096);
593
594
  if (hash_init(&bookmark_hash, &my_charset_bin, 16, 0, 0,
595
                  get_bookmark_hash_key, NULL, HASH_UNIQUE))
596
      goto err;
597
598
599
  if (my_init_dynamic_array(&plugin_dl_array,
600
                            sizeof(struct st_plugin_dl *),16,16) ||
601
      my_init_dynamic_array(&plugin_array,
602
                            sizeof(struct st_plugin_int *),16,16))
603
    goto err;
604
605
  initialized= 1;
606
607
  /*
608
    First we register builtin plugins
609
  */
992.1.39 by Monty Taylor
Removed the m4-based plugin system.
610
  for (builtins= drizzled_builtins; *builtins; builtins++)
1 by brian
clean slate
611
  {
177.4.3 by mark
ripped out more plugin ABI and API version checking, and plugin versions are now strings
612
    for (plugin= *builtins; plugin->name; plugin++)
1 by brian
clean slate
613
    {
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
614
      memset(&tmp, 0, sizeof(tmp));
1 by brian
clean slate
615
      tmp.plugin= plugin;
616
      tmp.name.str= (char *)plugin->name;
617
      tmp.name.length= strlen(plugin->name);
618
619
      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
620
      if (test_plugin_options(&tmp_root, &tmp, argc, argv))
1 by brian
clean slate
621
        continue;
622
971.1.54 by Monty Taylor
Trimmed out some plugin type stuff.
623
      if (register_builtin(&tmp, &plugin_ptr))
1 by brian
clean slate
624
        goto err_unlock;
625
626
      if (plugin_initialize(plugin_ptr))
627
        goto err_unlock;
628
629
    }
630
  }
631
632
633
  /* Register all dynamic plugins */
634
  if (!(flags & PLUGIN_INIT_SKIP_DYNAMIC_LOADING))
635
  {
636
    if (opt_plugin_load)
637
      plugin_load_list(&tmp_root, argc, argv, opt_plugin_load);
638
  }
639
640
  if (flags & PLUGIN_INIT_SKIP_INITIALIZATION)
641
    goto end;
642
643
  /*
644
    Now we initialize all remaining plugins
645
  */
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
646
  for (idx= 0; idx < plugin_array.elements; idx++)
1 by brian
clean slate
647
  {
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
648
    plugin_ptr= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
965.1.1 by Brian Aker
Refactor plugin loading to remove mask (one step closer to getting rid of
649
    if (plugin_ptr->isInited == false)
1 by brian
clean slate
650
    {
651
      if (plugin_initialize(plugin_ptr))
687 by Brian Aker
First vector to be removed from sql_plugin.
652
        plugin_del(plugin_ptr);
1 by brian
clean slate
653
    }
654
  }
655
656
657
end:
658
  free_root(&tmp_root, MYF(0));
659
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
660
  return(0);
1 by brian
clean slate
661
662
err_unlock:
663
err:
664
  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
665
  return(1);
1 by brian
clean slate
666
}
667
668
971.1.54 by Monty Taylor
Trimmed out some plugin type stuff.
669
static bool register_builtin(struct st_plugin_int *tmp,
1 by brian
clean slate
670
                             struct st_plugin_int **ptr)
671
{
672
971.1.52 by Monty Taylor
Did the finalizers. Renamed plugin_registry.
673
  PluginRegistry &registry= PluginRegistry::getPluginRegistry();
908.2.1 by Monty Taylor
First pass at refactoring plugins - factored out sql_map.
674
965.1.1 by Brian Aker
Refactor plugin loading to remove mask (one step closer to getting rid of
675
  tmp->isInited= false;
1 by brian
clean slate
676
  tmp->plugin_dl= 0;
677
481 by Brian Aker
Remove all of uchar.
678
  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
679
    return(1);
1 by brian
clean slate
680
681
  *ptr= *dynamic_element(&plugin_array, plugin_array.elements - 1,
682
                         struct st_plugin_int **)=
481 by Brian Aker
Remove all of uchar.
683
        (struct st_plugin_int *) memdup_root(&plugin_mem_root, (unsigned char*)tmp,
1 by brian
clean slate
684
                                             sizeof(struct st_plugin_int));
685
971.1.54 by Monty Taylor
Trimmed out some plugin type stuff.
686
  registry.add(*ptr);
1 by brian
clean slate
687
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
688
  return(0);
1 by brian
clean slate
689
}
690
691
692
/*
693
  called only by plugin_init()
694
*/
695
static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
696
                             const char *list)
697
{
698
  char buffer[FN_REFLEN];
699
  LEX_STRING name= {buffer, 0}, dl= {NULL, 0}, *str= &name;
700
  struct st_plugin_dl *plugin_dl;
971.1.59 by Monty Taylor
Renamed st_mysql_plugin to drizzled_plugin_manifest.
701
  struct drizzled_plugin_manifest *plugin;
1 by brian
clean slate
702
  char *p= buffer;
703
  while (list)
704
  {
705
    if (p == buffer + sizeof(buffer) - 1)
706
    {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
707
      errmsg_printf(ERRMSG_LVL_ERROR, _("plugin-load parameter too long"));
163 by Brian Aker
Merge Monty's code.
708
      return(true);
1 by brian
clean slate
709
    }
710
711
    switch ((*(p++)= *(list++))) {
712
    case '\0':
713
      list= NULL; /* terminate the loop */
714
      /* fall through */
715
    case ':':     /* can't use this as delimiter as it may be drive letter */
716
    case ';':
717
      str->str[str->length]= '\0';
718
      if (str == &name)  // load all plugins in named module
719
      {
720
        if (!name.length)
721
        {
722
          p--;    /* reset pointer */
723
          continue;
724
        }
725
726
        dl= name;
727
        if ((plugin_dl= plugin_dl_add(&dl, REPORT_TO_LOG)))
728
        {
177.4.3 by mark
ripped out more plugin ABI and API version checking, and plugin versions are now strings
729
          for (plugin= plugin_dl->plugins; plugin->name; plugin++)
1 by brian
clean slate
730
          {
731
            name.str= (char *) plugin->name;
732
            name.length= strlen(name.str);
733
734
            free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
735
            if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
736
              goto error;
737
          }
738
          plugin_dl_del(&dl); // reduce ref count
739
        }
740
      }
741
      else
742
      {
743
        free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
744
        if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
745
          goto error;
746
      }
747
      name.length= dl.length= 0;
748
      dl.str= NULL; name.str= p= buffer;
749
      str= &name;
750
      continue;
751
    case '=':
752
    case '#':
753
      if (str == &name)
754
      {
755
        name.str[name.length]= '\0';
756
        str= &dl;
757
        str->str= p;
758
        continue;
759
      }
760
    default:
761
      str->length++;
762
      continue;
763
    }
764
  }
163 by Brian Aker
Merge Monty's code.
765
  return(false);
1 by brian
clean slate
766
error:
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
767
  errmsg_printf(ERRMSG_LVL_ERROR, _("Couldn't load plugin named '%s' with soname '%s'."),
1 by brian
clean slate
768
                  name.str, dl.str);
163 by Brian Aker
Merge Monty's code.
769
  return(true);
1 by brian
clean slate
770
}
771
772
773
void plugin_shutdown(void)
774
{
962.1.6 by Brian Aker
Cut down on shutdown loop of plugins (cutting stuff out in order to simplify
775
  uint32_t idx;
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
776
  size_t count= plugin_array.elements;
777
  vector<st_plugin_int *> plugins;
778
  vector<st_plugin_dl *> dl;
1 by brian
clean slate
779
780
  if (initialized)
781
  {
782
    reap_needed= true;
783
962.1.6 by Brian Aker
Cut down on shutdown loop of plugins (cutting stuff out in order to simplify
784
    reap_plugins();
785
    unlock_variables(NULL, &global_system_variables);
786
    unlock_variables(NULL, &max_system_variables);
1 by brian
clean slate
787
788
    cleanup_variables(NULL, &global_system_variables);
789
    cleanup_variables(NULL, &max_system_variables);
790
791
    initialized= 0;
792
  }
793
794
  /* Dispose of the memory */
795
796
  delete_dynamic(&plugin_array);
797
798
  count= plugin_dl_array.elements;
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
799
  dl.reserve(count);
800
  for (idx= 0; idx < count; idx++)
801
    dl.push_back(*dynamic_element(&plugin_dl_array, idx,
802
                 struct st_plugin_dl **));
803
  for (idx= 0; idx < count; idx++)
804
    free_plugin_mem(dl[idx]);
1 by brian
clean slate
805
  delete_dynamic(&plugin_dl_array);
806
807
  hash_free(&bookmark_hash);
808
  free_root(&plugin_mem_root, MYF(0));
809
810
  global_variables_dynamic_size= 0;
811
}
812
813
/****************************************************************************
814
  Internal type declarations for variables support
815
****************************************************************************/
816
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
817
#undef DRIZZLE_SYSVAR_NAME
818
#define DRIZZLE_SYSVAR_NAME(name) name
1 by brian
clean slate
819
#define PLUGIN_VAR_TYPEMASK 0x007f
820
821
#define EXTRA_OPTIONS 3 /* options for: 'foo', 'plugin-foo' and NULL */
822
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
823
typedef DECLARE_DRIZZLE_SYSVAR_BASIC(sysvar_bool_t, bool);
520.1.22 by Brian Aker
Second pass of thd cleanup
824
typedef DECLARE_DRIZZLE_SessionVAR_BASIC(sessionvar_bool_t, bool);
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
825
typedef DECLARE_DRIZZLE_SYSVAR_BASIC(sysvar_str_t, char *);
520.1.22 by Brian Aker
Second pass of thd cleanup
826
typedef DECLARE_DRIZZLE_SessionVAR_BASIC(sessionvar_str_t, char *);
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
827
828
typedef DECLARE_DRIZZLE_SYSVAR_TYPELIB(sysvar_enum_t, unsigned long);
520.1.22 by Brian Aker
Second pass of thd cleanup
829
typedef DECLARE_DRIZZLE_SessionVAR_TYPELIB(sessionvar_enum_t, unsigned long);
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
830
typedef DECLARE_DRIZZLE_SYSVAR_TYPELIB(sysvar_set_t, uint64_t);
520.1.22 by Brian Aker
Second pass of thd cleanup
831
typedef DECLARE_DRIZZLE_SessionVAR_TYPELIB(sessionvar_set_t, uint64_t);
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
832
833
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_int_t, int);
834
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_long_t, long);
835
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_int64_t_t, int64_t);
836
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_uint_t, uint);
837
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_ulong_t, ulong);
838
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_uint64_t_t, uint64_t);
839
520.1.22 by Brian Aker
Second pass of thd cleanup
840
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_int_t, int);
841
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_long_t, long);
842
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_int64_t_t, int64_t);
843
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_uint_t, uint);
844
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_ulong_t, ulong);
845
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_uint64_t_t, uint64_t);
1 by brian
clean slate
846
520.1.22 by Brian Aker
Second pass of thd cleanup
847
typedef bool *(*mysql_sys_var_ptr_p)(Session* a_session, int offset);
1 by brian
clean slate
848
849
850
/****************************************************************************
851
  default variable data check and update functions
852
****************************************************************************/
853
654 by Brian Aker
Remove unused (yet more)
854
static int check_func_bool(Session *, struct st_mysql_sys_var *var,
1 by brian
clean slate
855
                           void *save, st_mysql_value *value)
856
{
857
  char buff[STRING_BUFFER_USUAL_SIZE];
858
  const char *strvalue= "NULL", *str;
859
  int result, length;
53.2.2 by Monty Taylor
Updated everything that needs updating to compile with -std=gnu99 -pedantic
860
  int64_t tmp;
1 by brian
clean slate
861
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
862
  if (value->value_type(value) == DRIZZLE_VALUE_TYPE_STRING)
1 by brian
clean slate
863
  {
864
    length= sizeof(buff);
865
    if (!(str= value->val_str(value, buff, &length)) ||
866
        (result= find_type(&bool_typelib, str, length, 1)-1) < 0)
867
    {
868
      if (str)
869
        strvalue= str;
870
      goto err;
871
    }
872
  }
873
  else
874
  {
875
    if (value->val_int(value, &tmp) < 0)
876
      goto err;
877
    if (tmp > 1)
878
    {
879
      llstr(tmp, buff);
880
      strvalue= buff;
881
      goto err;
882
    }
883
    result= (int) tmp;
884
  }
885
  *(int*)save= -result;
886
  return 0;
887
err:
888
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
889
  return 1;
890
}
891
892
520.1.22 by Brian Aker
Second pass of thd cleanup
893
static int check_func_int(Session *session, struct st_mysql_sys_var *var,
1 by brian
clean slate
894
                          void *save, st_mysql_value *value)
895
{
143 by Brian Aker
Bool cleanup.
896
  bool fixed;
53.2.2 by Monty Taylor
Updated everything that needs updating to compile with -std=gnu99 -pedantic
897
  int64_t tmp;
1 by brian
clean slate
898
  struct my_option options;
899
  value->val_int(value, &tmp);
900
  plugin_opt_set_limits(&options, var);
901
902
  if (var->flags & PLUGIN_VAR_UNSIGNED)
895 by Brian Aker
Completion (?) of uint conversion.
903
    *(uint32_t *)save= (uint32_t) getopt_ull_limit_value((uint64_t) tmp, &options,
1 by brian
clean slate
904
                                                   &fixed);
905
  else
906
    *(int *)save= (int) getopt_ll_limit_value(tmp, &options, &fixed);
907
520.1.22 by Brian Aker
Second pass of thd cleanup
908
  return throw_bounds_warning(session, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
152 by Brian Aker
longlong replacement
909
                              var->name, (int64_t) tmp);
1 by brian
clean slate
910
}
911
912
520.1.22 by Brian Aker
Second pass of thd cleanup
913
static int check_func_long(Session *session, struct st_mysql_sys_var *var,
1 by brian
clean slate
914
                          void *save, st_mysql_value *value)
915
{
143 by Brian Aker
Bool cleanup.
916
  bool fixed;
53.2.2 by Monty Taylor
Updated everything that needs updating to compile with -std=gnu99 -pedantic
917
  int64_t tmp;
1 by brian
clean slate
918
  struct my_option options;
919
  value->val_int(value, &tmp);
920
  plugin_opt_set_limits(&options, var);
921
922
  if (var->flags & PLUGIN_VAR_UNSIGNED)
151 by Brian Aker
Ulonglong to uint64_t
923
    *(ulong *)save= (ulong) getopt_ull_limit_value((uint64_t) tmp, &options,
1 by brian
clean slate
924
                                                   &fixed);
925
  else
926
    *(long *)save= (long) getopt_ll_limit_value(tmp, &options, &fixed);
927
520.1.22 by Brian Aker
Second pass of thd cleanup
928
  return throw_bounds_warning(session, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
152 by Brian Aker
longlong replacement
929
                              var->name, (int64_t) tmp);
1 by brian
clean slate
930
}
931
932
520.1.22 by Brian Aker
Second pass of thd cleanup
933
static int check_func_int64_t(Session *session, struct st_mysql_sys_var *var,
1 by brian
clean slate
934
                               void *save, st_mysql_value *value)
935
{
143 by Brian Aker
Bool cleanup.
936
  bool fixed;
53.2.2 by Monty Taylor
Updated everything that needs updating to compile with -std=gnu99 -pedantic
937
  int64_t tmp;
1 by brian
clean slate
938
  struct my_option options;
939
  value->val_int(value, &tmp);
940
  plugin_opt_set_limits(&options, var);
941
942
  if (var->flags & PLUGIN_VAR_UNSIGNED)
151 by Brian Aker
Ulonglong to uint64_t
943
    *(uint64_t *)save= getopt_ull_limit_value((uint64_t) tmp, &options,
1 by brian
clean slate
944
                                               &fixed);
945
  else
152 by Brian Aker
longlong replacement
946
    *(int64_t *)save= getopt_ll_limit_value(tmp, &options, &fixed);
1 by brian
clean slate
947
520.1.22 by Brian Aker
Second pass of thd cleanup
948
  return throw_bounds_warning(session, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
152 by Brian Aker
longlong replacement
949
                              var->name, (int64_t) tmp);
1 by brian
clean slate
950
}
951
654 by Brian Aker
Remove unused (yet more)
952
static int check_func_str(Session *session, struct st_mysql_sys_var *,
1 by brian
clean slate
953
                          void *save, st_mysql_value *value)
954
{
955
  char buff[STRING_BUFFER_USUAL_SIZE];
956
  const char *str;
957
  int length;
958
959
  length= sizeof(buff);
960
  if ((str= value->val_str(value, buff, &length)))
520.1.22 by Brian Aker
Second pass of thd cleanup
961
    str= session->strmake(str, length);
1 by brian
clean slate
962
  *(const char**)save= str;
963
  return 0;
964
}
965
966
654 by Brian Aker
Remove unused (yet more)
967
static int check_func_enum(Session *, struct st_mysql_sys_var *var,
1 by brian
clean slate
968
                           void *save, st_mysql_value *value)
969
{
970
  char buff[STRING_BUFFER_USUAL_SIZE];
971
  const char *strvalue= "NULL", *str;
972
  TYPELIB *typelib;
53.2.2 by Monty Taylor
Updated everything that needs updating to compile with -std=gnu99 -pedantic
973
  int64_t tmp;
1 by brian
clean slate
974
  long result;
975
  int length;
976
520.1.21 by Brian Aker
THD -> Session rename
977
  if (var->flags & PLUGIN_VAR_SessionLOCAL)
520.1.22 by Brian Aker
Second pass of thd cleanup
978
    typelib= ((sessionvar_enum_t*) var)->typelib;
1 by brian
clean slate
979
  else
980
    typelib= ((sysvar_enum_t*) var)->typelib;
981
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
982
  if (value->value_type(value) == DRIZZLE_VALUE_TYPE_STRING)
1 by brian
clean slate
983
  {
984
    length= sizeof(buff);
985
    if (!(str= value->val_str(value, buff, &length)))
986
      goto err;
987
    if ((result= (long)find_type(typelib, str, length, 1)-1) < 0)
988
    {
989
      strvalue= str;
990
      goto err;
991
    }
992
  }
993
  else
994
  {
995
    if (value->val_int(value, &tmp))
996
      goto err;
997
    if (tmp >= typelib->count)
998
    {
999
      llstr(tmp, buff);
1000
      strvalue= buff;
1001
      goto err;
1002
    }
1003
    result= (long) tmp;
1004
  }
1005
  *(long*)save= result;
1006
  return 0;
1007
err:
1008
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
1009
  return 1;
1010
}
1011
1012
654 by Brian Aker
Remove unused (yet more)
1013
static int check_func_set(Session *, struct st_mysql_sys_var *var,
1 by brian
clean slate
1014
                          void *save, st_mysql_value *value)
1015
{
1016
  char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
1017
  const char *strvalue= "NULL", *str;
1018
  TYPELIB *typelib;
151 by Brian Aker
Ulonglong to uint64_t
1019
  uint64_t result;
482 by Brian Aker
Remove uint.
1020
  uint32_t error_len;
1 by brian
clean slate
1021
  bool not_used;
1022
  int length;
1023
520.1.21 by Brian Aker
THD -> Session rename
1024
  if (var->flags & PLUGIN_VAR_SessionLOCAL)
520.1.22 by Brian Aker
Second pass of thd cleanup
1025
    typelib= ((sessionvar_set_t*) var)->typelib;
1 by brian
clean slate
1026
  else
1027
    typelib= ((sysvar_set_t*)var)->typelib;
1028
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1029
  if (value->value_type(value) == DRIZZLE_VALUE_TYPE_STRING)
1 by brian
clean slate
1030
  {
1031
    length= sizeof(buff);
1032
    if (!(str= value->val_str(value, buff, &length)))
1033
      goto err;
1034
    result= find_set(typelib, str, length, NULL,
1035
                     &error, &error_len, &not_used);
1036
    if (error_len)
1037
    {
629.5.2 by Toru Maesaka
Second pass of replacing MySQL's strmake() with libc calls
1038
      length= cmin(sizeof(buff), (unsigned long)error_len);
1039
      strncpy(buff, error, length);
1040
      buff[length]= '\0';
1 by brian
clean slate
1041
      strvalue= buff;
1042
      goto err;
1043
    }
1044
  }
1045
  else
1046
  {
53.2.2 by Monty Taylor
Updated everything that needs updating to compile with -std=gnu99 -pedantic
1047
    if (value->val_int(value, (int64_t *)&result))
1 by brian
clean slate
1048
      goto err;
398.1.8 by Monty Taylor
Enabled -Wlong-long.
1049
    if (unlikely((result >= (1UL << typelib->count)) &&
1 by brian
clean slate
1050
                 (typelib->count < sizeof(long)*8)))
1051
    {
1052
      llstr(result, buff);
1053
      strvalue= buff;
1054
      goto err;
1055
    }
1056
  }
151 by Brian Aker
Ulonglong to uint64_t
1057
  *(uint64_t*)save= result;
1 by brian
clean slate
1058
  return 0;
1059
err:
1060
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
1061
  return 1;
1062
}
1063
1064
654 by Brian Aker
Remove unused (yet more)
1065
static void update_func_bool(Session *, struct st_mysql_sys_var *,
1 by brian
clean slate
1066
                             void *tgt, const void *save)
1067
{
199 by Brian Aker
my_bool...
1068
  *(bool *) tgt= *(int *) save ? 1 : 0;
1 by brian
clean slate
1069
}
1070
1071
654 by Brian Aker
Remove unused (yet more)
1072
static void update_func_int(Session *, struct st_mysql_sys_var *,
1 by brian
clean slate
1073
                             void *tgt, const void *save)
1074
{
1075
  *(int *)tgt= *(int *) save;
1076
}
1077
1078
654 by Brian Aker
Remove unused (yet more)
1079
static void update_func_long(Session *, struct st_mysql_sys_var *,
1 by brian
clean slate
1080
                             void *tgt, const void *save)
1081
{
1082
  *(long *)tgt= *(long *) save;
1083
}
1084
1085
654 by Brian Aker
Remove unused (yet more)
1086
static void update_func_int64_t(Session *, struct st_mysql_sys_var *,
77.1.46 by Monty Taylor
Finished the warnings work!
1087
                                 void *tgt, const void *save)
1 by brian
clean slate
1088
{
152 by Brian Aker
longlong replacement
1089
  *(int64_t *)tgt= *(uint64_t *) save;
1 by brian
clean slate
1090
}
1091
1092
654 by Brian Aker
Remove unused (yet more)
1093
static void update_func_str(Session *, struct st_mysql_sys_var *var,
1 by brian
clean slate
1094
                             void *tgt, const void *save)
1095
{
1096
  char *old= *(char **) tgt;
1097
  *(char **)tgt= *(char **) save;
1098
  if (var->flags & PLUGIN_VAR_MEMALLOC)
1099
  {
656.1.19 by Monty Taylor
Removed my_strdup from drizzled/
1100
    *(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.
1101
    free(old);
656.1.52 by Monty Taylor
Added more return value checks.
1102
    /*
1103
     * There isn't a _really_ good thing to do here until this whole set_var
1104
     * mess gets redesigned
1105
     */
1106
    if (tgt == NULL)
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
1107
      errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory."));
656.1.52 by Monty Taylor
Added more return value checks.
1108
1 by brian
clean slate
1109
  }
1110
}
1111
1112
1113
/****************************************************************************
1114
  System Variables support
1115
****************************************************************************/
1116
1117
970.1.1 by Brian Aker
Removed dead passed variables.
1118
sys_var *find_sys_var(Session *, const char *str, uint32_t length)
1 by brian
clean slate
1119
{
1120
  sys_var *var;
1121
  sys_var_pluginvar *pi= NULL;
971.1.19 by Monty Taylor
Remove most of plugin_ref. Fix several leaks (where the malloc was happening but never freed). One step away from no more plugin_ref. Yippee. It's so much easier the second time you try to do this.
1122
  st_plugin_int *plugin;
1 by brian
clean slate
1123
658 by Brian Aker
Part removal of my_pthread.h
1124
  pthread_rwlock_rdlock(&LOCK_system_variables_hash);
1 by brian
clean slate
1125
  if ((var= intern_find_sys_var(str, length, false)) &&
1126
      (pi= var->cast_pluginvar()))
1127
  {
658 by Brian Aker
Part removal of my_pthread.h
1128
    pthread_rwlock_unlock(&LOCK_system_variables_hash);
971.1.19 by Monty Taylor
Remove most of plugin_ref. Fix several leaks (where the malloc was happening but never freed). One step away from no more plugin_ref. Yippee. It's so much easier the second time you try to do this.
1129
    if (!(plugin= pi->plugin))
1 by brian
clean slate
1130
      var= NULL; /* failed to lock it, it must be uninstalling */
971.1.19 by Monty Taylor
Remove most of plugin_ref. Fix several leaks (where the malloc was happening but never freed). One step away from no more plugin_ref. Yippee. It's so much easier the second time you try to do this.
1131
    else if (plugin->isInited == false)
1 by brian
clean slate
1132
    {
1133
      var= NULL;
1134
    }
1135
  }
1136
  else
658 by Brian Aker
Part removal of my_pthread.h
1137
    pthread_rwlock_unlock(&LOCK_system_variables_hash);
1 by brian
clean slate
1138
1139
  /*
1140
    If the variable exists but the plugin it is associated with is not ready
1141
    then the intern_plugin_lock did not raise an error, so we do it here.
1142
  */
1143
  if (pi && !var)
1144
    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
1145
  return(var);
1 by brian
clean slate
1146
}
1147
1148
1149
/*
1150
  called by register_var, construct_options and test_plugin_options.
1151
  Returns the 'bookmark' for the named variable.
1152
  LOCK_system_variables_hash should be at least read locked
1153
*/
138 by Brian Aker
Refactoring around sql_plugin.
1154
static st_bookmark *find_bookmark(const char *plugin, const char *name, int flags)
1 by brian
clean slate
1155
{
1156
  st_bookmark *result= NULL;
482 by Brian Aker
Remove uint.
1157
  uint32_t namelen, length, pluginlen= 0;
1 by brian
clean slate
1158
  char *varname, *p;
1159
520.1.21 by Brian Aker
THD -> Session rename
1160
  if (!(flags & PLUGIN_VAR_SessionLOCAL))
1 by brian
clean slate
1161
    return NULL;
1162
1163
  namelen= strlen(name);
1164
  if (plugin)
1165
    pluginlen= strlen(plugin) + 1;
1166
  length= namelen + pluginlen + 2;
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
1167
  varname= (char*) malloc(length);
1 by brian
clean slate
1168
1169
  if (plugin)
1170
  {
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
1171
    sprintf(varname+1,"%s_%s",plugin,name);
1 by brian
clean slate
1172
    for (p= varname + 1; *p; p++)
1173
      if (*p == '-')
1174
        *p= '_';
1175
  }
1176
  else
1177
    memcpy(varname + 1, name, namelen + 1);
1178
1179
  varname[0]= flags & PLUGIN_VAR_TYPEMASK;
1180
1181
  result= (st_bookmark*) hash_search(&bookmark_hash,
481 by Brian Aker
Remove all of uchar.
1182
                                     (const unsigned char*) varname, length - 1);
1 by brian
clean slate
1183
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
1184
  free(varname);
1 by brian
clean slate
1185
  return result;
1186
}
1187
1188
1189
/*
520.1.22 by Brian Aker
Second pass of thd cleanup
1190
  returns a bookmark for session-local variables, creating if neccessary.
1191
  returns null for non session-local variables.
1 by brian
clean slate
1192
  Requires that a write lock is obtained on LOCK_system_variables_hash
1193
*/
1194
static st_bookmark *register_var(const char *plugin, const char *name,
1195
                                 int flags)
1196
{
482 by Brian Aker
Remove uint.
1197
  uint32_t length= strlen(plugin) + strlen(name) + 3, size= 0, offset, new_size;
1 by brian
clean slate
1198
  st_bookmark *result;
1199
  char *varname, *p;
1200
520.1.21 by Brian Aker
THD -> Session rename
1201
  if (!(flags & PLUGIN_VAR_SessionLOCAL))
1 by brian
clean slate
1202
    return NULL;
1203
1204
  switch (flags & PLUGIN_VAR_TYPEMASK) {
1205
  case PLUGIN_VAR_BOOL:
937.2.12 by Stewart Smith
ensure correct alignment of all plugin variables. Manifesting as innodb_mysql test failure with SIGBUS on Sparc
1206
    size= ALIGN_SIZE(sizeof(bool));
1 by brian
clean slate
1207
    break;
1208
  case PLUGIN_VAR_INT:
937.2.12 by Stewart Smith
ensure correct alignment of all plugin variables. Manifesting as innodb_mysql test failure with SIGBUS on Sparc
1209
    size= ALIGN_SIZE(sizeof(int));
1 by brian
clean slate
1210
    break;
1211
  case PLUGIN_VAR_LONG:
1212
  case PLUGIN_VAR_ENUM:
937.2.12 by Stewart Smith
ensure correct alignment of all plugin variables. Manifesting as innodb_mysql test failure with SIGBUS on Sparc
1213
    size= ALIGN_SIZE(sizeof(long));
1 by brian
clean slate
1214
    break;
1215
  case PLUGIN_VAR_LONGLONG:
1216
  case PLUGIN_VAR_SET:
937.2.12 by Stewart Smith
ensure correct alignment of all plugin variables. Manifesting as innodb_mysql test failure with SIGBUS on Sparc
1217
    size= ALIGN_SIZE(sizeof(uint64_t));
1 by brian
clean slate
1218
    break;
1219
  case PLUGIN_VAR_STR:
937.2.12 by Stewart Smith
ensure correct alignment of all plugin variables. Manifesting as innodb_mysql test failure with SIGBUS on Sparc
1220
    size= ALIGN_SIZE(sizeof(char*));
1 by brian
clean slate
1221
    break;
1222
  default:
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
1223
    assert(0);
1 by brian
clean slate
1224
    return NULL;
1225
  };
1226
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
1227
  varname= ((char*) malloc(length));
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
1228
  sprintf(varname+1, "%s_%s", plugin, name);
1 by brian
clean slate
1229
  for (p= varname + 1; *p; p++)
1230
    if (*p == '-')
1231
      *p= '_';
1232
1233
  if (!(result= find_bookmark(NULL, varname + 1, flags)))
1234
  {
1235
    result= (st_bookmark*) alloc_root(&plugin_mem_root,
1236
                                      sizeof(struct st_bookmark) + length-1);
1237
    varname[0]= flags & PLUGIN_VAR_TYPEMASK;
1238
    memcpy(result->key, varname, length);
1239
    result->name_len= length - 2;
1240
    result->offset= -1;
1241
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
1242
    assert(size && !(size & (size-1))); /* must be power of 2 */
1 by brian
clean slate
1243
1244
    offset= global_system_variables.dynamic_variables_size;
1245
    offset= (offset + size - 1) & ~(size - 1);
1246
    result->offset= (int) offset;
1247
1248
    new_size= (offset + size + 63) & ~63;
1249
1250
    if (new_size > global_variables_dynamic_size)
1251
    {
656.1.46 by Monty Taylor
More malloc return cleanups.
1252
      char* tmpptr= NULL;
1253
      if (!(tmpptr=
1254
              (char *)realloc(global_system_variables.dynamic_variables_ptr,
1255
                              new_size)))
1256
        return NULL;
1257
      global_system_variables.dynamic_variables_ptr= tmpptr;
1258
      tmpptr= NULL;
1259
      if (!(tmpptr=
1260
              (char *)realloc(max_system_variables.dynamic_variables_ptr,
1261
                              new_size)))
1262
        return NULL;
1263
      max_system_variables.dynamic_variables_ptr= tmpptr;
656.1.26 by Monty Taylor
Finally removed all of the my_malloc stuff.
1264
           
1 by brian
clean slate
1265
      /*
1266
        Clear the new variable value space. This is required for string
1267
        variables. If their value is non-NULL, it must point to a valid
1268
        string.
1269
      */
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
1270
      memset(global_system_variables.dynamic_variables_ptr +
1271
             global_variables_dynamic_size, 0,
1272
             new_size - global_variables_dynamic_size);
1273
      memset(max_system_variables.dynamic_variables_ptr +
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1274
             global_variables_dynamic_size, 0,
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
1275
             new_size - global_variables_dynamic_size);
1 by brian
clean slate
1276
      global_variables_dynamic_size= new_size;
1277
    }
1278
1279
    global_system_variables.dynamic_variables_head= offset;
1280
    max_system_variables.dynamic_variables_head= offset;
1281
    global_system_variables.dynamic_variables_size= offset + size;
1282
    max_system_variables.dynamic_variables_size= offset + size;
1283
    global_system_variables.dynamic_variables_version++;
1284
    max_system_variables.dynamic_variables_version++;
1285
1286
    result->version= global_system_variables.dynamic_variables_version;
1287
1288
    /* this should succeed because we have already checked if a dup exists */
481 by Brian Aker
Remove all of uchar.
1289
    if (my_hash_insert(&bookmark_hash, (unsigned char*) result))
1 by brian
clean slate
1290
    {
1291
      fprintf(stderr, "failed to add placeholder to hash");
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
1292
      assert(0);
1 by brian
clean slate
1293
    }
1294
  }
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
1295
  free(varname);
1 by brian
clean slate
1296
  return result;
1297
}
1298
1299
1300
/*
520.1.22 by Brian Aker
Second pass of thd cleanup
1301
  returns a pointer to the memory which holds the session-local variable or
1302
  a pointer to the global variable if session==null.
1 by brian
clean slate
1303
  If required, will sync with global variables if the requested variable
1304
  has not yet been allocated in the current thread.
1305
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
1306
static unsigned char *intern_sys_var_ptr(Session* session, int offset, bool global_lock)
1 by brian
clean slate
1307
{
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
1308
  assert(offset >= 0);
895 by Brian Aker
Completion (?) of uint conversion.
1309
  assert((uint32_t)offset <= global_system_variables.dynamic_variables_head);
1 by brian
clean slate
1310
520.1.22 by Brian Aker
Second pass of thd cleanup
1311
  if (!session)
481 by Brian Aker
Remove all of uchar.
1312
    return (unsigned char*) global_system_variables.dynamic_variables_ptr + offset;
1 by brian
clean slate
1313
1314
  /*
1315
    dynamic_variables_head points to the largest valid offset
1316
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
1317
  if (!session->variables.dynamic_variables_ptr ||
895 by Brian Aker
Completion (?) of uint conversion.
1318
      (uint32_t)offset > session->variables.dynamic_variables_head)
1 by brian
clean slate
1319
  {
482 by Brian Aker
Remove uint.
1320
    uint32_t idx;
1 by brian
clean slate
1321
658 by Brian Aker
Part removal of my_pthread.h
1322
    pthread_rwlock_rdlock(&LOCK_system_variables_hash);
1 by brian
clean slate
1323
656.1.46 by Monty Taylor
More malloc return cleanups.
1324
    char *tmpptr= NULL;
1325
    if (!(tmpptr= (char *)realloc(session->variables.dynamic_variables_ptr,
1326
                                  global_variables_dynamic_size)))
1327
      return NULL;
1328
    session->variables.dynamic_variables_ptr= tmpptr;
1 by brian
clean slate
1329
1330
    if (global_lock)
1331
      pthread_mutex_lock(&LOCK_global_system_variables);
1332
1333
    safe_mutex_assert_owner(&LOCK_global_system_variables);
1334
520.1.22 by Brian Aker
Second pass of thd cleanup
1335
    memcpy(session->variables.dynamic_variables_ptr +
1336
             session->variables.dynamic_variables_size,
1 by brian
clean slate
1337
           global_system_variables.dynamic_variables_ptr +
520.1.22 by Brian Aker
Second pass of thd cleanup
1338
             session->variables.dynamic_variables_size,
1 by brian
clean slate
1339
           global_system_variables.dynamic_variables_size -
520.1.22 by Brian Aker
Second pass of thd cleanup
1340
             session->variables.dynamic_variables_size);
1 by brian
clean slate
1341
1342
    /*
1343
      now we need to iterate through any newly copied 'defaults'
1344
      and if it is a string type with MEMALLOC flag, we need to strdup
1345
    */
1346
    for (idx= 0; idx < bookmark_hash.records; idx++)
1347
    {
1348
      sys_var_pluginvar *pi;
1349
      sys_var *var;
1350
      st_bookmark *v= (st_bookmark*) hash_element(&bookmark_hash,idx);
1351
520.1.22 by Brian Aker
Second pass of thd cleanup
1352
      if (v->version <= session->variables.dynamic_variables_version ||
1 by brian
clean slate
1353
          !(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
1354
          !(pi= var->cast_pluginvar()) ||
1355
          v->key[0] != (pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
1356
        continue;
1357
1358
      /* Here we do anything special that may be required of the data types */
1359
1360
      if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
1361
          pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC)
1362
      {
520.1.22 by Brian Aker
Second pass of thd cleanup
1363
         char **pp= (char**) (session->variables.dynamic_variables_ptr +
1 by brian
clean slate
1364
                             *(int*)(pi->plugin_var + 1));
1365
         if ((*pp= *(char**) (global_system_variables.dynamic_variables_ptr +
1366
                             *(int*)(pi->plugin_var + 1))))
656.1.19 by Monty Taylor
Removed my_strdup from drizzled/
1367
           *pp= strdup(*pp);
656.1.52 by Monty Taylor
Added more return value checks.
1368
         if (*pp == NULL)
1369
           return NULL;
1 by brian
clean slate
1370
      }
1371
    }
1372
1373
    if (global_lock)
1374
      pthread_mutex_unlock(&LOCK_global_system_variables);
1375
520.1.22 by Brian Aker
Second pass of thd cleanup
1376
    session->variables.dynamic_variables_version=
1 by brian
clean slate
1377
           global_system_variables.dynamic_variables_version;
520.1.22 by Brian Aker
Second pass of thd cleanup
1378
    session->variables.dynamic_variables_head=
1 by brian
clean slate
1379
           global_system_variables.dynamic_variables_head;
520.1.22 by Brian Aker
Second pass of thd cleanup
1380
    session->variables.dynamic_variables_size=
1 by brian
clean slate
1381
           global_system_variables.dynamic_variables_size;
1382
658 by Brian Aker
Part removal of my_pthread.h
1383
    pthread_rwlock_unlock(&LOCK_system_variables_hash);
1 by brian
clean slate
1384
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
1385
  return (unsigned char*)session->variables.dynamic_variables_ptr + offset;
1386
}
1387
1388
static bool *mysql_sys_var_ptr_bool(Session* a_session, int offset)
1389
{
1390
  return (bool *)intern_sys_var_ptr(a_session, offset, true);
1391
}
1392
1393
static int *mysql_sys_var_ptr_int(Session* a_session, int offset)
1394
{
1395
  return (int *)intern_sys_var_ptr(a_session, offset, true);
1396
}
1397
1398
static long *mysql_sys_var_ptr_long(Session* a_session, int offset)
1399
{
1400
  return (long *)intern_sys_var_ptr(a_session, offset, true);
1401
}
1402
1403
static int64_t *mysql_sys_var_ptr_int64_t(Session* a_session, int offset)
1404
{
1405
  return (int64_t *)intern_sys_var_ptr(a_session, offset, true);
1406
}
1407
1408
static char **mysql_sys_var_ptr_str(Session* a_session, int offset)
1409
{
1410
  return (char **)intern_sys_var_ptr(a_session, offset, true);
1411
}
1412
1413
static uint64_t *mysql_sys_var_ptr_set(Session* a_session, int offset)
1414
{
1415
  return (uint64_t *)intern_sys_var_ptr(a_session, offset, true);
1416
}
1417
1418
static unsigned long *mysql_sys_var_ptr_enum(Session* a_session, int offset)
1419
{
1420
  return (unsigned long *)intern_sys_var_ptr(a_session, offset, true);
1421
}
1422
1423
1424
void plugin_sessionvar_init(Session *session)
1425
{
971.1.21 by Monty Taylor
Store StorageEngine in system variables, rather than storage engine plugin.
1426
  session->variables.storage_engine= NULL;
520.1.22 by Brian Aker
Second pass of thd cleanup
1427
  cleanup_variables(session, &session->variables);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1428
520.1.22 by Brian Aker
Second pass of thd cleanup
1429
  session->variables= global_system_variables;
971.1.21 by Monty Taylor
Store StorageEngine in system variables, rather than storage engine plugin.
1430
  session->variables.storage_engine= NULL;
1 by brian
clean slate
1431
1432
  /* we are going to allocate these lazily */
520.1.22 by Brian Aker
Second pass of thd cleanup
1433
  session->variables.dynamic_variables_version= 0;
1434
  session->variables.dynamic_variables_size= 0;
1435
  session->variables.dynamic_variables_ptr= 0;
1 by brian
clean slate
1436
971.1.21 by Monty Taylor
Store StorageEngine in system variables, rather than storage engine plugin.
1437
  session->variables.storage_engine= global_system_variables.storage_engine;
1 by brian
clean slate
1438
}
1439
1440
1441
/*
1442
  Unlocks all system variables which hold a reference
1443
*/
654 by Brian Aker
Remove unused (yet more)
1444
static void unlock_variables(Session *, struct system_variables *vars)
1 by brian
clean slate
1445
{
971.1.21 by Monty Taylor
Store StorageEngine in system variables, rather than storage engine plugin.
1446
  vars->storage_engine= NULL;
1 by brian
clean slate
1447
}
1448
1449
1450
/*
1451
  Frees memory used by system variables
1452
1453
  Unlike plugin_vars_free_values() it frees all variables of all plugins,
1454
  it's used on shutdown.
1455
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
1456
static void cleanup_variables(Session *session, struct system_variables *vars)
1 by brian
clean slate
1457
{
1458
  st_bookmark *v;
1459
  sys_var_pluginvar *pivar;
1460
  sys_var *var;
1461
  int flags;
482 by Brian Aker
Remove uint.
1462
  uint32_t idx;
1 by brian
clean slate
1463
658 by Brian Aker
Part removal of my_pthread.h
1464
  pthread_rwlock_rdlock(&LOCK_system_variables_hash);
1 by brian
clean slate
1465
  for (idx= 0; idx < bookmark_hash.records; idx++)
1466
  {
1467
    v= (st_bookmark*) hash_element(&bookmark_hash, idx);
1468
    if (v->version > vars->dynamic_variables_version ||
1469
        !(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
1470
        !(pivar= var->cast_pluginvar()) ||
1471
        v->key[0] != (pivar->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
1472
      continue;
1473
1474
    flags= pivar->plugin_var->flags;
1475
1476
    if ((flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
520.1.21 by Brian Aker
THD -> Session rename
1477
        flags & PLUGIN_VAR_SessionLOCAL && flags & PLUGIN_VAR_MEMALLOC)
1 by brian
clean slate
1478
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
1479
      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.
1480
      free(*ptr);
1 by brian
clean slate
1481
      *ptr= NULL;
1482
    }
1483
  }
658 by Brian Aker
Part removal of my_pthread.h
1484
  pthread_rwlock_unlock(&LOCK_system_variables_hash);
1 by brian
clean slate
1485
971.1.21 by Monty Taylor
Store StorageEngine in system variables, rather than storage engine plugin.
1486
  assert(vars->storage_engine == NULL);
1 by brian
clean slate
1487
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.
1488
  free(vars->dynamic_variables_ptr);
1 by brian
clean slate
1489
  vars->dynamic_variables_ptr= NULL;
1490
  vars->dynamic_variables_size= 0;
1491
  vars->dynamic_variables_version= 0;
1492
}
1493
1494
520.1.22 by Brian Aker
Second pass of thd cleanup
1495
void plugin_sessionvar_cleanup(Session *session)
1 by brian
clean slate
1496
{
520.1.22 by Brian Aker
Second pass of thd cleanup
1497
  unlock_variables(session, &session->variables);
1498
  cleanup_variables(session, &session->variables);
1 by brian
clean slate
1499
}
1500
1501
1502
/**
1503
  @brief Free values of thread variables of a plugin.
1504
1505
  This must be called before a plugin is deleted. Otherwise its
1506
  variables are no longer accessible and the value space is lost. Note
1507
  that only string values with PLUGIN_VAR_MEMALLOC are allocated and
1508
  must be freed.
1509
1510
  @param[in]        vars        Chain of system variables of a plugin
1511
*/
1512
1513
static void plugin_vars_free_values(sys_var *vars)
1514
{
1515
1516
  for (sys_var *var= vars; var; var= var->next)
1517
  {
1518
    sys_var_pluginvar *piv= var->cast_pluginvar();
1519
    if (piv &&
1520
        ((piv->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR) &&
1521
        (piv->plugin_var->flags & PLUGIN_VAR_MEMALLOC))
1522
    {
1523
      /* Free the string from global_system_variables. */
1524
      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.
1525
      free(*valptr);
1 by brian
clean slate
1526
      *valptr= NULL;
1527
    }
1528
  }
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
1529
  return;
1 by brian
clean slate
1530
}
1531
1532
1533
bool sys_var_pluginvar::check_update_type(Item_result type)
1534
{
1535
  if (is_readonly())
1536
    return 1;
1537
  switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
1538
  case PLUGIN_VAR_INT:
1539
  case PLUGIN_VAR_LONG:
1540
  case PLUGIN_VAR_LONGLONG:
1541
    return type != INT_RESULT;
1542
  case PLUGIN_VAR_STR:
1543
    return type != STRING_RESULT;
1544
  default:
1545
    return 0;
1546
  }
1547
}
1548
1549
1550
SHOW_TYPE sys_var_pluginvar::show_type()
1551
{
1552
  switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
1553
  case PLUGIN_VAR_BOOL:
1554
    return SHOW_MY_BOOL;
1555
  case PLUGIN_VAR_INT:
1556
    return SHOW_INT;
1557
  case PLUGIN_VAR_LONG:
1558
    return SHOW_LONG;
1559
  case PLUGIN_VAR_LONGLONG:
1560
    return SHOW_LONGLONG;
1561
  case PLUGIN_VAR_STR:
1562
    return SHOW_CHAR_PTR;
1563
  case PLUGIN_VAR_ENUM:
1564
  case PLUGIN_VAR_SET:
1565
    return SHOW_CHAR;
1566
  default:
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
1567
    assert(0);
1 by brian
clean slate
1568
    return SHOW_UNDEF;
1569
  }
1570
}
1571
1572
520.1.22 by Brian Aker
Second pass of thd cleanup
1573
unsigned char* sys_var_pluginvar::real_value_ptr(Session *session, enum_var_type type)
1 by brian
clean slate
1574
{
520.1.22 by Brian Aker
Second pass of thd cleanup
1575
  assert(session || (type == OPT_GLOBAL));
520.1.21 by Brian Aker
THD -> Session rename
1576
  if (plugin_var->flags & PLUGIN_VAR_SessionLOCAL)
1 by brian
clean slate
1577
  {
1578
    if (type == OPT_GLOBAL)
520.1.22 by Brian Aker
Second pass of thd cleanup
1579
      session= NULL;
1 by brian
clean slate
1580
520.1.22 by Brian Aker
Second pass of thd cleanup
1581
    return intern_sys_var_ptr(session, *(int*) (plugin_var+1), false);
1 by brian
clean slate
1582
  }
481 by Brian Aker
Remove all of uchar.
1583
  return *(unsigned char**) (plugin_var+1);
1 by brian
clean slate
1584
}
1585
1586
1587
TYPELIB* sys_var_pluginvar::plugin_var_typelib(void)
1588
{
520.1.21 by Brian Aker
THD -> Session rename
1589
  switch (plugin_var->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_SessionLOCAL)) {
1 by brian
clean slate
1590
  case PLUGIN_VAR_ENUM:
1591
    return ((sysvar_enum_t *)plugin_var)->typelib;
1592
  case PLUGIN_VAR_SET:
1593
    return ((sysvar_set_t *)plugin_var)->typelib;
520.1.21 by Brian Aker
THD -> Session rename
1594
  case PLUGIN_VAR_ENUM | PLUGIN_VAR_SessionLOCAL:
520.1.22 by Brian Aker
Second pass of thd cleanup
1595
    return ((sessionvar_enum_t *)plugin_var)->typelib;
520.1.21 by Brian Aker
THD -> Session rename
1596
  case PLUGIN_VAR_SET | PLUGIN_VAR_SessionLOCAL:
520.1.22 by Brian Aker
Second pass of thd cleanup
1597
    return ((sessionvar_set_t *)plugin_var)->typelib;
1 by brian
clean slate
1598
  default:
1599
    return NULL;
1600
  }
1601
  return NULL;
1602
}
1603
1604
779.3.10 by Monty Taylor
Turned on -Wshadow.
1605
unsigned char* sys_var_pluginvar::value_ptr(Session *session, enum_var_type type, const LEX_STRING *)
1 by brian
clean slate
1606
{
481 by Brian Aker
Remove all of uchar.
1607
  unsigned char* result;
1 by brian
clean slate
1608
520.1.22 by Brian Aker
Second pass of thd cleanup
1609
  result= real_value_ptr(session, type);
1 by brian
clean slate
1610
1611
  if ((plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_ENUM)
481 by Brian Aker
Remove all of uchar.
1612
    result= (unsigned char*) get_type(plugin_var_typelib(), *(ulong*)result);
1 by brian
clean slate
1613
  else if ((plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_SET)
1614
  {
1615
    char buffer[STRING_BUFFER_USUAL_SIZE];
1616
    String str(buffer, sizeof(buffer), system_charset_info);
1617
    TYPELIB *typelib= plugin_var_typelib();
151 by Brian Aker
Ulonglong to uint64_t
1618
    uint64_t mask= 1, value= *(uint64_t*) result;
482 by Brian Aker
Remove uint.
1619
    uint32_t i;
1 by brian
clean slate
1620
1621
    str.length(0);
1622
    for (i= 0; i < typelib->count; i++, mask<<=1)
1623
    {
1624
      if (!(value & mask))
1625
        continue;
1626
      str.append(typelib->type_names[i], typelib->type_lengths[i]);
1627
      str.append(',');
1628
    }
1629
481 by Brian Aker
Remove all of uchar.
1630
    result= (unsigned char*) "";
1 by brian
clean slate
1631
    if (str.length())
520.1.22 by Brian Aker
Second pass of thd cleanup
1632
      result= (unsigned char*) session->strmake(str.ptr(), str.length()-1);
1 by brian
clean slate
1633
  }
1634
  return result;
1635
}
1636
1637
520.1.22 by Brian Aker
Second pass of thd cleanup
1638
bool sys_var_pluginvar::check(Session *session, set_var *var)
1 by brian
clean slate
1639
{
1640
  st_item_value_holder value;
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
1641
  assert(is_readonly() || plugin_var->check);
1 by brian
clean slate
1642
1643
  value.value_type= item_value_type;
1644
  value.val_str= item_val_str;
1645
  value.val_int= item_val_int;
1646
  value.val_real= item_val_real;
1647
  value.item= var->value;
1648
1649
  return is_readonly() ||
520.1.22 by Brian Aker
Second pass of thd cleanup
1650
         plugin_var->check(session, plugin_var, &var->save_result, &value);
1 by brian
clean slate
1651
}
1652
1653
520.1.22 by Brian Aker
Second pass of thd cleanup
1654
void sys_var_pluginvar::set_default(Session *session, enum_var_type type)
1 by brian
clean slate
1655
{
1656
  const void *src;
1657
  void *tgt;
1658
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
1659
  assert(is_readonly() || plugin_var->update);
1 by brian
clean slate
1660
1661
  if (is_readonly())
1662
    return;
1663
1664
  pthread_mutex_lock(&LOCK_global_system_variables);
520.1.22 by Brian Aker
Second pass of thd cleanup
1665
  tgt= real_value_ptr(session, type);
1 by brian
clean slate
1666
  src= ((void **) (plugin_var + 1) + 1);
1667
520.1.21 by Brian Aker
THD -> Session rename
1668
  if (plugin_var->flags & PLUGIN_VAR_SessionLOCAL)
1 by brian
clean slate
1669
  {
1670
    if (type != OPT_GLOBAL)
520.1.22 by Brian Aker
Second pass of thd cleanup
1671
      src= real_value_ptr(session, OPT_GLOBAL);
1 by brian
clean slate
1672
    else
1673
    switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
1674
	case PLUGIN_VAR_INT:
520.1.22 by Brian Aker
Second pass of thd cleanup
1675
	  src= &((sessionvar_uint_t*) plugin_var)->def_val;
1 by brian
clean slate
1676
	  break;
1677
	case PLUGIN_VAR_LONG:
520.1.22 by Brian Aker
Second pass of thd cleanup
1678
	  src= &((sessionvar_ulong_t*) plugin_var)->def_val;
1 by brian
clean slate
1679
	  break;
1680
	case PLUGIN_VAR_LONGLONG:
520.1.22 by Brian Aker
Second pass of thd cleanup
1681
	  src= &((sessionvar_uint64_t_t*) plugin_var)->def_val;
1 by brian
clean slate
1682
	  break;
1683
	case PLUGIN_VAR_ENUM:
520.1.22 by Brian Aker
Second pass of thd cleanup
1684
	  src= &((sessionvar_enum_t*) plugin_var)->def_val;
1 by brian
clean slate
1685
	  break;
1686
	case PLUGIN_VAR_SET:
520.1.22 by Brian Aker
Second pass of thd cleanup
1687
	  src= &((sessionvar_set_t*) plugin_var)->def_val;
1 by brian
clean slate
1688
	  break;
1689
	case PLUGIN_VAR_BOOL:
520.1.22 by Brian Aker
Second pass of thd cleanup
1690
	  src= &((sessionvar_bool_t*) plugin_var)->def_val;
1 by brian
clean slate
1691
	  break;
1692
	case PLUGIN_VAR_STR:
520.1.22 by Brian Aker
Second pass of thd cleanup
1693
	  src= &((sessionvar_str_t*) plugin_var)->def_val;
1 by brian
clean slate
1694
	  break;
1695
	default:
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
1696
	  assert(0);
1 by brian
clean slate
1697
	}
1698
  }
1699
520.1.22 by Brian Aker
Second pass of thd cleanup
1700
  /* session must equal current_session if PLUGIN_VAR_SessionLOCAL flag is set */
520.1.21 by Brian Aker
THD -> Session rename
1701
  assert(!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) ||
520.1.22 by Brian Aker
Second pass of thd cleanup
1702
              session == current_session);
1 by brian
clean slate
1703
520.1.21 by Brian Aker
THD -> Session rename
1704
  if (!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) || type == OPT_GLOBAL)
1 by brian
clean slate
1705
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
1706
    plugin_var->update(session, plugin_var, tgt, src);
1 by brian
clean slate
1707
    pthread_mutex_unlock(&LOCK_global_system_variables);
1708
  }
1709
  else
1710
  {
1711
    pthread_mutex_unlock(&LOCK_global_system_variables);
520.1.22 by Brian Aker
Second pass of thd cleanup
1712
    plugin_var->update(session, plugin_var, tgt, src);
1 by brian
clean slate
1713
  }
1714
}
1715
1716
520.1.22 by Brian Aker
Second pass of thd cleanup
1717
bool sys_var_pluginvar::update(Session *session, set_var *var)
1 by brian
clean slate
1718
{
1719
  void *tgt;
1720
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
1721
  assert(is_readonly() || plugin_var->update);
1 by brian
clean slate
1722
520.1.22 by Brian Aker
Second pass of thd cleanup
1723
  /* session must equal current_session if PLUGIN_VAR_SessionLOCAL flag is set */
520.1.21 by Brian Aker
THD -> Session rename
1724
  assert(!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) ||
520.1.22 by Brian Aker
Second pass of thd cleanup
1725
              session == current_session);
1 by brian
clean slate
1726
1727
  if (is_readonly())
1728
    return 1;
1729
1730
  pthread_mutex_lock(&LOCK_global_system_variables);
520.1.22 by Brian Aker
Second pass of thd cleanup
1731
  tgt= real_value_ptr(session, var->type);
1 by brian
clean slate
1732
520.1.21 by Brian Aker
THD -> Session rename
1733
  if (!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) || var->type == OPT_GLOBAL)
1 by brian
clean slate
1734
  {
1735
    /* variable we are updating has global scope, so we unlock after updating */
520.1.22 by Brian Aker
Second pass of thd cleanup
1736
    plugin_var->update(session, plugin_var, tgt, &var->save_result);
1 by brian
clean slate
1737
    pthread_mutex_unlock(&LOCK_global_system_variables);
1738
  }
1739
  else
1740
  {
1741
    pthread_mutex_unlock(&LOCK_global_system_variables);
520.1.22 by Brian Aker
Second pass of thd cleanup
1742
    plugin_var->update(session, plugin_var, tgt, &var->save_result);
1 by brian
clean slate
1743
  }
1744
 return 0;
1745
}
1746
1747
1748
#define OPTION_SET_LIMITS(type, options, opt) \
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
1749
  options->var_type= type;                    \
1750
  options->def_value= (opt)->def_val;         \
1751
  options->min_value= (opt)->min_val;         \
1752
  options->max_value= (opt)->max_val;         \
1 by brian
clean slate
1753
  options->block_size= (long) (opt)->blk_sz
1754
1755
1756
static void plugin_opt_set_limits(struct my_option *options,
1757
                                  const struct st_mysql_sys_var *opt)
1758
{
1759
  options->sub_size= 0;
1760
1761
  switch (opt->flags & (PLUGIN_VAR_TYPEMASK |
520.1.21 by Brian Aker
THD -> Session rename
1762
                        PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL)) {
1 by brian
clean slate
1763
  /* global system variables */
1764
  case PLUGIN_VAR_INT:
1765
    OPTION_SET_LIMITS(GET_INT, options, (sysvar_int_t*) opt);
1766
    break;
1767
  case PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED:
1768
    OPTION_SET_LIMITS(GET_UINT, options, (sysvar_uint_t*) opt);
1769
    break;
1770
  case PLUGIN_VAR_LONG:
1771
    OPTION_SET_LIMITS(GET_LONG, options, (sysvar_long_t*) opt);
1772
    break;
1773
  case PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED:
896.4.16 by Stewart Smith
for getopt, replace GET_ULONG with GET_UINT32.
1774
    OPTION_SET_LIMITS(GET_ULONG_IS_FAIL, options, (sysvar_ulong_t*) opt);
1 by brian
clean slate
1775
    break;
1776
  case PLUGIN_VAR_LONGLONG:
152 by Brian Aker
longlong replacement
1777
    OPTION_SET_LIMITS(GET_LL, options, (sysvar_int64_t_t*) opt);
1 by brian
clean slate
1778
    break;
1779
  case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED:
151 by Brian Aker
Ulonglong to uint64_t
1780
    OPTION_SET_LIMITS(GET_ULL, options, (sysvar_uint64_t_t*) opt);
1 by brian
clean slate
1781
    break;
1782
  case PLUGIN_VAR_ENUM:
1783
    options->var_type= GET_ENUM;
1784
    options->typelib= ((sysvar_enum_t*) opt)->typelib;
1785
    options->def_value= ((sysvar_enum_t*) opt)->def_val;
1786
    options->min_value= options->block_size= 0;
1787
    options->max_value= options->typelib->count - 1;
1788
    break;
1789
  case PLUGIN_VAR_SET:
1790
    options->var_type= GET_SET;
1791
    options->typelib= ((sysvar_set_t*) opt)->typelib;
1792
    options->def_value= ((sysvar_set_t*) opt)->def_val;
1793
    options->min_value= options->block_size= 0;
398.1.8 by Monty Taylor
Enabled -Wlong-long.
1794
    options->max_value= (1UL << options->typelib->count) - 1;
1 by brian
clean slate
1795
    break;
1796
  case PLUGIN_VAR_BOOL:
1797
    options->var_type= GET_BOOL;
1798
    options->def_value= ((sysvar_bool_t*) opt)->def_val;
1799
    break;
1800
  case PLUGIN_VAR_STR:
1801
    options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ?
1802
                        GET_STR_ALLOC : GET_STR);
157 by Brian Aker
Second pass cleanup on removal of my_uint types
1803
    options->def_value= (intptr_t) ((sysvar_str_t*) opt)->def_val;
1 by brian
clean slate
1804
    break;
1805
  /* threadlocal variables */
520.1.21 by Brian Aker
THD -> Session rename
1806
  case PLUGIN_VAR_INT | PLUGIN_VAR_SessionLOCAL:
520.1.22 by Brian Aker
Second pass of thd cleanup
1807
    OPTION_SET_LIMITS(GET_INT, options, (sessionvar_int_t*) opt);
1 by brian
clean slate
1808
    break;
520.1.21 by Brian Aker
THD -> Session rename
1809
  case PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
520.1.22 by Brian Aker
Second pass of thd cleanup
1810
    OPTION_SET_LIMITS(GET_UINT, options, (sessionvar_uint_t*) opt);
1 by brian
clean slate
1811
    break;
520.1.21 by Brian Aker
THD -> Session rename
1812
  case PLUGIN_VAR_LONG | PLUGIN_VAR_SessionLOCAL:
520.1.22 by Brian Aker
Second pass of thd cleanup
1813
    OPTION_SET_LIMITS(GET_LONG, options, (sessionvar_long_t*) opt);
1 by brian
clean slate
1814
    break;
520.1.21 by Brian Aker
THD -> Session rename
1815
  case PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
896.4.16 by Stewart Smith
for getopt, replace GET_ULONG with GET_UINT32.
1816
    OPTION_SET_LIMITS(GET_ULONG_IS_FAIL, options, (sessionvar_ulong_t*) opt);
1 by brian
clean slate
1817
    break;
520.1.21 by Brian Aker
THD -> Session rename
1818
  case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_SessionLOCAL:
520.1.22 by Brian Aker
Second pass of thd cleanup
1819
    OPTION_SET_LIMITS(GET_LL, options, (sessionvar_int64_t_t*) opt);
1 by brian
clean slate
1820
    break;
520.1.21 by Brian Aker
THD -> Session rename
1821
  case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
520.1.22 by Brian Aker
Second pass of thd cleanup
1822
    OPTION_SET_LIMITS(GET_ULL, options, (sessionvar_uint64_t_t*) opt);
1 by brian
clean slate
1823
    break;
520.1.21 by Brian Aker
THD -> Session rename
1824
  case PLUGIN_VAR_ENUM | PLUGIN_VAR_SessionLOCAL:
1 by brian
clean slate
1825
    options->var_type= GET_ENUM;
520.1.22 by Brian Aker
Second pass of thd cleanup
1826
    options->typelib= ((sessionvar_enum_t*) opt)->typelib;
1827
    options->def_value= ((sessionvar_enum_t*) opt)->def_val;
1 by brian
clean slate
1828
    options->min_value= options->block_size= 0;
1829
    options->max_value= options->typelib->count - 1;
1830
    break;
520.1.21 by Brian Aker
THD -> Session rename
1831
  case PLUGIN_VAR_SET | PLUGIN_VAR_SessionLOCAL:
1 by brian
clean slate
1832
    options->var_type= GET_SET;
520.1.22 by Brian Aker
Second pass of thd cleanup
1833
    options->typelib= ((sessionvar_set_t*) opt)->typelib;
1834
    options->def_value= ((sessionvar_set_t*) opt)->def_val;
1 by brian
clean slate
1835
    options->min_value= options->block_size= 0;
398.1.8 by Monty Taylor
Enabled -Wlong-long.
1836
    options->max_value= (1UL << options->typelib->count) - 1;
1 by brian
clean slate
1837
    break;
520.1.21 by Brian Aker
THD -> Session rename
1838
  case PLUGIN_VAR_BOOL | PLUGIN_VAR_SessionLOCAL:
1 by brian
clean slate
1839
    options->var_type= GET_BOOL;
520.1.22 by Brian Aker
Second pass of thd cleanup
1840
    options->def_value= ((sessionvar_bool_t*) opt)->def_val;
1 by brian
clean slate
1841
    break;
520.1.21 by Brian Aker
THD -> Session rename
1842
  case PLUGIN_VAR_STR | PLUGIN_VAR_SessionLOCAL:
1 by brian
clean slate
1843
    options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ?
1844
                        GET_STR_ALLOC : GET_STR);
520.1.22 by Brian Aker
Second pass of thd cleanup
1845
    options->def_value= (intptr_t) ((sessionvar_str_t*) opt)->def_val;
1 by brian
clean slate
1846
    break;
1847
  default:
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
1848
    assert(0);
1 by brian
clean slate
1849
  }
1850
  options->arg_type= REQUIRED_ARG;
1851
  if (opt->flags & PLUGIN_VAR_NOCMDARG)
1852
    options->arg_type= NO_ARG;
1853
  if (opt->flags & PLUGIN_VAR_OPCMDARG)
1854
    options->arg_type= OPT_ARG;
1855
}
1856
143 by Brian Aker
Bool cleanup.
1857
extern "C" bool get_one_plugin_option(int optid, const struct my_option *,
1 by brian
clean slate
1858
                                         char *);
1859
654 by Brian Aker
Remove unused (yet more)
1860
bool get_one_plugin_option(int, const struct my_option *, char *)
1 by brian
clean slate
1861
{
1862
  return 0;
1863
}
1864
1865
1866
static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
138 by Brian Aker
Refactoring around sql_plugin.
1867
                             my_option *options, bool can_disable)
1 by brian
clean slate
1868
{
1869
  const char *plugin_name= tmp->plugin->name;
482 by Brian Aker
Remove uint.
1870
  uint32_t namelen= strlen(plugin_name), optnamelen;
1871
  uint32_t buffer_length= namelen * 4 + (can_disable ? 75 : 10);
1 by brian
clean slate
1872
  char *name= (char*) alloc_root(mem_root, buffer_length) + 1;
1873
  char *optname, *p;
1874
  int index= 0, offset= 0;
1875
  st_mysql_sys_var *opt, **plugin_option;
1876
  st_bookmark *v;
1877
1878
  /* support --skip-plugin-foo syntax */
1879
  memcpy(name, plugin_name, namelen + 1);
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
1880
  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
1881
  sprintf(name+namelen+1, "plugin-%s", name);
1 by brian
clean slate
1882
  /* Now we have namelen + 1 + 7 + namelen + 1 == namelen * 2 + 9. */
1883
1884
  for (p= name + namelen*2 + 8; p > name; p--)
1885
    if (*p == '_')
1886
      *p= '-';
1887
1888
  if (can_disable)
1889
  {
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
1890
    sprintf(name+namelen*2+10,
1891
            "Enable %s plugin. Disable with --skip-%s (will save memory).",
1892
            plugin_name, name);
1 by brian
clean slate
1893
    /*
1894
      Now we have namelen * 2 + 10 (one char unused) + 7 + namelen + 9 +
1895
      20 + namelen + 20 + 1 == namelen * 4 + 67.
1896
    */
1897
1898
    options[0].comment= name + namelen*2 + 10;
1899
  }
1900
1901
  options[1].name= (options[0].name= name) + namelen + 1;
1902
  options[0].id= options[1].id= 256; /* must be >255. dup id ok */
1903
  options[0].var_type= options[1].var_type= GET_BOOL;
1904
  options[0].arg_type= options[1].arg_type= NO_ARG;
138 by Brian Aker
Refactoring around sql_plugin.
1905
  options[0].def_value= options[1].def_value= true;
1 by brian
clean slate
1906
  options[0].value= options[0].u_max_value=
77.1.78 by Monty Taylor
One last bunch of warnings edits.
1907
  options[1].value= options[1].u_max_value= (char**) (name - 1);
1 by brian
clean slate
1908
  options+= 2;
1909
1910
  /*
1911
    Two passes as the 2nd pass will take pointer addresses for use
1912
    by my_getopt and register_var() in the first pass uses realloc
1913
  */
1914
1915
  for (plugin_option= tmp->plugin->system_vars;
1916
       plugin_option && *plugin_option; plugin_option++, index++)
1917
  {
1918
    opt= *plugin_option;
520.1.21 by Brian Aker
THD -> Session rename
1919
    if (!(opt->flags & PLUGIN_VAR_SessionLOCAL))
1 by brian
clean slate
1920
      continue;
1921
    if (!(register_var(name, opt->name, opt->flags)))
1922
      continue;
1923
    switch (opt->flags & PLUGIN_VAR_TYPEMASK) {
1924
    case PLUGIN_VAR_BOOL:
520.1.22 by Brian Aker
Second pass of thd cleanup
1925
      (((sessionvar_bool_t *)opt)->resolve)= mysql_sys_var_ptr_bool;
1 by brian
clean slate
1926
      break;
1927
    case PLUGIN_VAR_INT:
520.1.22 by Brian Aker
Second pass of thd cleanup
1928
      (((sessionvar_int_t *)opt)->resolve)= mysql_sys_var_ptr_int;
1 by brian
clean slate
1929
      break;
1930
    case PLUGIN_VAR_LONG:
520.1.22 by Brian Aker
Second pass of thd cleanup
1931
      (((sessionvar_long_t *)opt)->resolve)= mysql_sys_var_ptr_long;
1 by brian
clean slate
1932
      break;
1933
    case PLUGIN_VAR_LONGLONG:
520.1.22 by Brian Aker
Second pass of thd cleanup
1934
      (((sessionvar_int64_t_t *)opt)->resolve)= mysql_sys_var_ptr_int64_t;
1 by brian
clean slate
1935
      break;
1936
    case PLUGIN_VAR_STR:
520.1.22 by Brian Aker
Second pass of thd cleanup
1937
      (((sessionvar_str_t *)opt)->resolve)= mysql_sys_var_ptr_str;
1 by brian
clean slate
1938
      break;
1939
    case PLUGIN_VAR_ENUM:
520.1.22 by Brian Aker
Second pass of thd cleanup
1940
      (((sessionvar_enum_t *)opt)->resolve)= mysql_sys_var_ptr_enum;
1 by brian
clean slate
1941
      break;
1942
    case PLUGIN_VAR_SET:
520.1.22 by Brian Aker
Second pass of thd cleanup
1943
      (((sessionvar_set_t *)opt)->resolve)= mysql_sys_var_ptr_set;
1 by brian
clean slate
1944
      break;
1945
    default:
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
1946
      errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown variable type code 0x%x in plugin '%s'."),
1 by brian
clean slate
1947
                      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
1948
      return(-1);
1 by brian
clean slate
1949
    };
1950
  }
1951
1952
  for (plugin_option= tmp->plugin->system_vars;
1953
       plugin_option && *plugin_option; plugin_option++, index++)
1954
  {
1955
    switch ((opt= *plugin_option)->flags & PLUGIN_VAR_TYPEMASK) {
1956
    case PLUGIN_VAR_BOOL:
1957
      if (!opt->check)
1958
        opt->check= check_func_bool;
1959
      if (!opt->update)
1960
        opt->update= update_func_bool;
1961
      break;
1962
    case PLUGIN_VAR_INT:
1963
      if (!opt->check)
1964
        opt->check= check_func_int;
1965
      if (!opt->update)
1966
        opt->update= update_func_int;
1967
      break;
1968
    case PLUGIN_VAR_LONG:
1969
      if (!opt->check)
1970
        opt->check= check_func_long;
1971
      if (!opt->update)
1972
        opt->update= update_func_long;
1973
      break;
1974
    case PLUGIN_VAR_LONGLONG:
1975
      if (!opt->check)
152 by Brian Aker
longlong replacement
1976
        opt->check= check_func_int64_t;
1 by brian
clean slate
1977
      if (!opt->update)
152 by Brian Aker
longlong replacement
1978
        opt->update= update_func_int64_t;
1 by brian
clean slate
1979
      break;
1980
    case PLUGIN_VAR_STR:
1981
      if (!opt->check)
1982
        opt->check= check_func_str;
1983
      if (!opt->update)
1984
      {
1985
        opt->update= update_func_str;
9 by Brian Aker
Warnings cleanup
1986
        if ((opt->flags & (PLUGIN_VAR_MEMALLOC | PLUGIN_VAR_READONLY)) == false)
1 by brian
clean slate
1987
        {
1988
          opt->flags|= PLUGIN_VAR_READONLY;
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
1989
          errmsg_printf(ERRMSG_LVL_WARN, _("Server variable %s of plugin %s was forced "
1 by brian
clean slate
1990
                            "to be read-only: string variable without "
338 by Monty Taylor
Tagged more strings.
1991
                            "update_func and PLUGIN_VAR_MEMALLOC flag"),
1 by brian
clean slate
1992
                            opt->name, plugin_name);
1993
        }
1994
      }
1995
      break;
1996
    case PLUGIN_VAR_ENUM:
1997
      if (!opt->check)
1998
        opt->check= check_func_enum;
1999
      if (!opt->update)
2000
        opt->update= update_func_long;
2001
      break;
2002
    case PLUGIN_VAR_SET:
2003
      if (!opt->check)
2004
        opt->check= check_func_set;
2005
      if (!opt->update)
152 by Brian Aker
longlong replacement
2006
        opt->update= update_func_int64_t;
1 by brian
clean slate
2007
      break;
2008
    default:
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
2009
      errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown variable type code 0x%x in plugin '%s'."),
1 by brian
clean slate
2010
                      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
2011
      return(-1);
1 by brian
clean slate
2012
    }
2013
520.1.21 by Brian Aker
THD -> Session rename
2014
    if ((opt->flags & (PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_SessionLOCAL))
1 by brian
clean slate
2015
                    == PLUGIN_VAR_NOCMDOPT)
2016
      continue;
2017
2018
    if (!opt->name)
2019
    {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
2020
      errmsg_printf(ERRMSG_LVL_ERROR, _("Missing variable name in plugin '%s'."),
1 by brian
clean slate
2021
                      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
2022
      return(-1);
1 by brian
clean slate
2023
    }
2024
520.1.21 by Brian Aker
THD -> Session rename
2025
    if (!(opt->flags & PLUGIN_VAR_SessionLOCAL))
1 by brian
clean slate
2026
    {
2027
      optnamelen= strlen(opt->name);
2028
      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
2029
      sprintf(optname, "%s-%s", name, opt->name);
1 by brian
clean slate
2030
      optnamelen= namelen + optnamelen + 1;
2031
    }
2032
    else
2033
    {
2034
      /* this should not fail because register_var should create entry */
2035
      if (!(v= find_bookmark(name, opt->name, opt->flags)))
2036
      {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
2037
        errmsg_printf(ERRMSG_LVL_ERROR, _("Thread local variable '%s' not allocated "
338 by Monty Taylor
Tagged more strings.
2038
                        "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
2039
        return(-1);
1 by brian
clean slate
2040
      }
2041
2042
      *(int*)(opt + 1)= offset= v->offset;
2043
2044
      if (opt->flags & PLUGIN_VAR_NOCMDOPT)
2045
        continue;
2046
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2047
      optname= (char*) memdup_root(mem_root, v->key + 1,
1 by brian
clean slate
2048
                                   (optnamelen= v->name_len) + 1);
2049
    }
2050
2051
    /* convert '_' to '-' */
2052
    for (p= optname; *p; p++)
2053
      if (*p == '_')
2054
        *p= '-';
2055
2056
    options->name= optname;
2057
    options->comment= opt->comment;
2058
    options->app_type= opt;
2059
    options->id= (options-1)->id + 1;
2060
2061
    plugin_opt_set_limits(options, opt);
2062
520.1.21 by Brian Aker
THD -> Session rename
2063
    if (opt->flags & PLUGIN_VAR_SessionLOCAL)
77.1.78 by Monty Taylor
One last bunch of warnings edits.
2064
      options->value= options->u_max_value= (char**)
1 by brian
clean slate
2065
        (global_system_variables.dynamic_variables_ptr + offset);
2066
    else
77.1.78 by Monty Taylor
One last bunch of warnings edits.
2067
      options->value= options->u_max_value= *(char***) (opt + 1);
1 by brian
clean slate
2068
2069
    options[1]= options[0];
2070
    options[1].name= p= (char*) alloc_root(mem_root, optnamelen + 8);
2071
    options[1].comment= 0; // hidden
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
2072
    sprintf(p,"plugin-%s",optname);
1 by brian
clean slate
2073
2074
    options+= 2;
2075
  }
2076
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
2077
  return(0);
1 by brian
clean slate
2078
}
2079
2080
2081
static my_option *construct_help_options(MEM_ROOT *mem_root,
2082
                                         struct st_plugin_int *p)
2083
{
2084
  st_mysql_sys_var **opt;
2085
  my_option *opts;
138 by Brian Aker
Refactoring around sql_plugin.
2086
  bool can_disable;
482 by Brian Aker
Remove uint.
2087
  uint32_t count= EXTRA_OPTIONS;
1 by brian
clean slate
2088
9 by Brian Aker
Warnings cleanup
2089
  for (opt= p->plugin->system_vars; opt && *opt; opt++, count+= 2) {};
1 by brian
clean slate
2090
2091
  if (!(opts= (my_option*) alloc_root(mem_root, sizeof(my_option) * count)))
1019.1.6 by Brian Aker
A number of random cleanups.
2092
    return NULL;
1 by brian
clean slate
2093
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
2094
  memset(opts, 0, sizeof(my_option) * count);
1 by brian
clean slate
2095
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
2096
  if ((my_strcasecmp(&my_charset_utf8_general_ci, p->name.str, "MyISAM") == 0))
138 by Brian Aker
Refactoring around sql_plugin.
2097
    can_disable= false;
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
2098
  else if ((my_strcasecmp(&my_charset_utf8_general_ci, p->name.str, "MEMORY") == 0))
138 by Brian Aker
Refactoring around sql_plugin.
2099
    can_disable= false;
2100
  else
2101
    can_disable= true;
2102
2103
2104
  if (construct_options(mem_root, p, opts, can_disable))
1019.1.6 by Brian Aker
A number of random cleanups.
2105
    return NULL;
1 by brian
clean slate
2106
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
2107
  return(opts);
1 by brian
clean slate
2108
}
2109
2110
2111
/*
2112
  SYNOPSIS
2113
    test_plugin_options()
2114
    tmp_root                    temporary scratch space
2115
    plugin                      internal plugin structure
2116
    argc                        user supplied arguments
2117
    argv                        user supplied arguments
2118
    default_enabled             default plugin enable status
2119
  RETURNS:
2120
    0 SUCCESS - plugin should be enabled/loaded
2121
  NOTE:
2122
    Requires that a write-lock is held on LOCK_system_variables_hash
2123
*/
2124
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
2125
                               int *argc, char **argv)
1 by brian
clean slate
2126
{
2127
  struct sys_var_chain chain= { NULL, NULL };
138 by Brian Aker
Refactoring around sql_plugin.
2128
  bool can_disable;
1 by brian
clean slate
2129
  MEM_ROOT *mem_root= alloc_root_inited(&tmp->mem_root) ?
2130
                      &tmp->mem_root : &plugin_mem_root;
2131
  st_mysql_sys_var **opt;
2132
  my_option *opts= NULL;
2133
  char *p, *varname;
2134
  int error;
2135
  st_mysql_sys_var *o;
2136
  sys_var *v;
2137
  struct st_bookmark *var;
482 by Brian Aker
Remove uint.
2138
  uint32_t len, count= EXTRA_OPTIONS;
51.1.62 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE
2139
  assert(tmp->plugin && tmp->name.str);
1 by brian
clean slate
2140
2141
  for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
2142
    count+= 2; /* --{plugin}-{optname} and --plugin-{plugin}-{optname} */
2143
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
2144
  if ((my_strcasecmp(&my_charset_utf8_general_ci, tmp->name.str, "MyISAM") == 0))
138 by Brian Aker
Refactoring around sql_plugin.
2145
    can_disable= false;
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
2146
  else if ((my_strcasecmp(&my_charset_utf8_general_ci, tmp->name.str, "MEMORY") == 0))
138 by Brian Aker
Refactoring around sql_plugin.
2147
    can_disable= false;
2148
  else
2149
    can_disable= true;
1 by brian
clean slate
2150
2151
  if (count > EXTRA_OPTIONS || (*argc > 1))
2152
  {
2153
    if (!(opts= (my_option*) alloc_root(tmp_root, sizeof(my_option) * count)))
2154
    {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
2155
      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
2156
      return(-1);
1 by brian
clean slate
2157
    }
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
2158
    memset(opts, 0, sizeof(my_option) * count);
1 by brian
clean slate
2159
138 by Brian Aker
Refactoring around sql_plugin.
2160
    if (construct_options(tmp_root, tmp, opts, can_disable))
1 by brian
clean slate
2161
    {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
2162
      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
2163
      return(-1);
1 by brian
clean slate
2164
    }
2165
2166
    error= handle_options(argc, &argv, opts, get_one_plugin_option);
2167
    (*argc)++; /* add back one for the program name */
2168
2169
    if (error)
2170
    {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
2171
       errmsg_printf(ERRMSG_LVL_ERROR, _("Parsing options for plugin '%s' failed."),
1 by brian
clean slate
2172
                       tmp->name.str);
2173
       goto err;
2174
    }
2175
  }
2176
2177
  error= 1;
2178
779.3.53 by Monty Taylor
Revert the fail.
2179
  {
2180
    for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
2181
    {
2182
      if (((o= *opt)->flags & PLUGIN_VAR_NOSYSVAR))
2183
        continue;
2184
2185
      if ((var= find_bookmark(tmp->name.str, o->name, o->flags)))
2186
        v= new (mem_root) sys_var_pluginvar(var->key + 1, o);
2187
      else
2188
      {
2189
        len= tmp->name.length + strlen(o->name) + 2;
2190
        varname= (char*) alloc_root(mem_root, len);
2191
        sprintf(varname,"%s-%s",tmp->name.str,o->name);
2192
        my_casedn_str(&my_charset_utf8_general_ci, varname);
2193
2194
        for (p= varname; *p; p++)
2195
          if (*p == '-')
2196
            *p= '_';
2197
2198
        v= new (mem_root) sys_var_pluginvar(varname, o);
2199
      }
2200
      assert(v); /* check that an object was actually constructed */
2201
2202
      /*
2203
        Add to the chain of variables.
2204
        Done like this for easier debugging so that the
2205
        pointer to v is not lost on optimized builds.
2206
      */
2207
      v->chain_sys_var(&chain);
2208
    }
2209
    if (chain.first)
2210
    {
2211
      chain.last->next = NULL;
2212
      if (mysql_add_sys_var_chain(chain.first, NULL))
2213
      {
2214
        errmsg_printf(ERRMSG_LVL_ERROR, _("Plugin '%s' has conflicting system variables"),
2215
                        tmp->name.str);
2216
        goto err;
2217
      }
2218
      tmp->system_vars= chain.first;
2219
    }
2220
    return(0);
2221
  }
2222
1 by brian
clean slate
2223
err:
2224
  if (opts)
2225
    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
2226
  return(error);
1 by brian
clean slate
2227
}
2228
2229
2230
/****************************************************************************
2231
  Help Verbose text with Plugin System Variables
2232
****************************************************************************/
2233
2234
static int option_cmp(my_option *a, my_option *b)
2235
{
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
2236
  return my_strcasecmp(&my_charset_utf8_general_ci, a->name, b->name);
1 by brian
clean slate
2237
}
2238
2239
482 by Brian Aker
Remove uint.
2240
void my_print_help_inc_plugins(my_option *main_options, uint32_t size)
1 by brian
clean slate
2241
{
2242
  DYNAMIC_ARRAY all_options;
2243
  struct st_plugin_int *p;
2244
  MEM_ROOT mem_root;
2245
  my_option *opt;
2246
2247
  init_alloc_root(&mem_root, 4096, 4096);
2248
  my_init_dynamic_array(&all_options, sizeof(my_option), size, size/4);
2249
2250
  if (initialized)
482 by Brian Aker
Remove uint.
2251
    for (uint32_t idx= 0; idx < plugin_array.elements; idx++)
1 by brian
clean slate
2252
    {
2253
      p= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
2254
2255
      if (!p->plugin->system_vars ||
2256
          !(opt= construct_help_options(&mem_root, p)))
2257
        continue;
2258
2259
      /* Only options with a non-NULL comment are displayed in help text */
2260
      for (;opt->id; opt++)
2261
        if (opt->comment)
481 by Brian Aker
Remove all of uchar.
2262
          insert_dynamic(&all_options, (unsigned char*) opt);
1 by brian
clean slate
2263
    }
2264
2265
  for (;main_options->id; main_options++)
481 by Brian Aker
Remove all of uchar.
2266
    insert_dynamic(&all_options, (unsigned char*) main_options);
1 by brian
clean slate
2267
2268
  sort_dynamic(&all_options, (qsort_cmp) option_cmp);
2269
2270
  /* main_options now points to the empty option terminator */
481 by Brian Aker
Remove all of uchar.
2271
  insert_dynamic(&all_options, (unsigned char*) main_options);
1 by brian
clean slate
2272
2273
  my_print_help((my_option*) all_options.buffer);
2274
  my_print_variables((my_option*) all_options.buffer);
2275
2276
  delete_dynamic(&all_options);
2277
  free_root(&mem_root, MYF(0));
2278
}
2279