Commit dc24473c authored by antony@ppcg5.local's avatar antony@ppcg5.local

WL#2936

  "Server Variables for Plugins"
  Implement support for plugins to declare server variables.
  Demonstrate functionality by removing InnoDB specific code from sql/*
  New feature for HASH - HASH_UNIQUE flag
  New feature for DYNAMIC_ARRAY - initializer accepts preallocated ptr.
  Completed support for plugin reference counting.
parent 83a5eac0
......@@ -27,6 +27,9 @@ extern "C" {
*/
#define HASH_OVERHEAD (sizeof(char*)*2)
/* flags for hash_init */
#define HASH_UNIQUE 1 /* hash_insert fails on duplicate key */
typedef byte *(*hash_get_key)(const byte *,uint*,my_bool);
typedef void (*hash_free_key)(void *);
......
......@@ -29,12 +29,16 @@ C_MODE_START
#define GET_STR 9
#define GET_STR_ALLOC 10
#define GET_DISABLED 11
#define GET_ENUM 12
#define GET_SET 13
#define GET_ASK_ADDR 128
#define GET_TYPE_MASK 127
enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG };
struct st_typelib;
struct my_option
{
const char *name; /* Name of the option */
......@@ -42,7 +46,7 @@ struct my_option
const char *comment; /* option comment, for autom. --help */
gptr *value; /* The variable value */
gptr *u_max_value; /* The user def. max variable value */
const char **str_values; /* Pointer to possible values */
struct st_typelib *typelib; /* Pointer to possible values */
ulong var_type;
enum get_opt_arg_type arg_type;
longlong def_value; /* Default value */
......@@ -50,7 +54,7 @@ struct my_option
longlong max_value; /* Max allowed value */
longlong sub_size; /* Subtract this from given value */
long block_size; /* Value should be a mult. of this */
int app_type; /* To be used by an application */
long app_type; /* To be used by an application */
};
typedef my_bool (* my_get_one_option) (int, const struct my_option *, char * );
......@@ -58,6 +62,7 @@ typedef void (* my_error_reporter) (enum loglevel level, const char *format, ...
extern char *disabled_my_option;
extern my_bool my_getopt_print_errors;
extern my_bool my_getopt_skip_unknown;
extern my_error_reporter my_getopt_error_reporter;
extern int handle_options (int *argc, char ***argv,
......
......@@ -758,8 +758,15 @@ extern my_bool real_open_cached_file(IO_CACHE *cache);
extern void close_cached_file(IO_CACHE *cache);
File create_temp_file(char *to, const char *dir, const char *pfx,
int mode, myf MyFlags);
#define my_init_dynamic_array(A,B,C,D) init_dynamic_array(A,B,C,D CALLER_INFO)
#define my_init_dynamic_array_ci(A,B,C,D) init_dynamic_array(A,B,C,D ORIG_CALLER_INFO)
#define my_init_dynamic_array(A,B,C,D) init_dynamic_array2(A,B,NULL,C,D CALLER_INFO)
#define my_init_dynamic_array_ci(A,B,C,D) init_dynamic_array2(A,B,NULL,C,D ORIG_CALLER_INFO)
#define my_init_dynamic_array2(A,B,C,D,E) init_dynamic_array2(A,B,C,D,E CALLER_INFO)
#define my_init_dynamic_array2_ci(A,B,C,D,E) init_dynamic_array2(A,B,C,D,E ORIG_CALLER_INFO)
extern my_bool init_dynamic_array2(DYNAMIC_ARRAY *array,uint element_size,
void *init_buffer, uint init_alloc,
uint alloc_increment
CALLER_INFO_PROTO);
/* init_dynamic_array() function is deprecated */
extern my_bool init_dynamic_array(DYNAMIC_ARRAY *array,uint element_size,
uint init_alloc,uint alloc_increment
CALLER_INFO_PROTO);
......
......@@ -67,7 +67,6 @@ typedef int my_socket;
#include "mysql_version.h"
#include "mysql_com.h"
#include "mysql_time.h"
#include "typelib.h"
#include "my_list.h" /* for LISTs used in 'MYSQL' and 'MYSQL_STMT' */
......@@ -126,6 +125,8 @@ typedef unsigned long long my_ulonglong;
#endif
#endif
#include "typelib.h"
#define MYSQL_COUNT_ERROR (~(my_ulonglong) 0)
/* backward compatibility define - to be removed eventually */
......
This diff is collapsed.
......@@ -79,6 +79,7 @@ extern const char * NEAR globerrs[]; /* my_error_messages is here */
#define EXIT_NO_PTR_TO_VARIABLE 10
#define EXIT_CANNOT_CONNECT_TO_SERVICE 11
#define EXIT_OPTION_DISABLED 12
#define EXIT_ARGUMENT_INVALID 13
#ifdef __cplusplus
......
......@@ -26,6 +26,7 @@ typedef struct st_typelib { /* Different types saved here */
unsigned int *type_lengths;
} TYPELIB;
extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position);
extern int find_type(char *x,TYPELIB *typelib,unsigned int full_name);
extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
extern const char *get_type(TYPELIB *typelib,unsigned int nr);
......
......@@ -20,8 +20,8 @@ character-sets-dir VALUE
basedir VALUE
server_id VALUE
skip-stack-trace VALUE
skip-innodb VALUE
skip-ndbcluster VALUE
skip-plugin-innodb VALUE
skip-plugin-ndbcluster VALUE
log-output VALUE
SHOW INSTANCE OPTIONS mysqld2;
option_name value
......@@ -38,8 +38,8 @@ character-sets-dir VALUE
basedir VALUE
server_id VALUE
skip-stack-trace VALUE
skip-innodb VALUE
skip-ndbcluster VALUE
skip-plugin-innodb VALUE
skip-plugin-ndbcluster VALUE
nonguarded VALUE
log-output VALUE
START INSTANCE mysqld2;
......
......@@ -169,6 +169,8 @@ lock tables mysql.slow_log READ LOCAL, mysql.general_log READ LOCAL;
unlock tables;
set global general_log='OFF';
set global slow_query_log='OFF';
set @save_storage_engine= @@session.storage_engine;
set storage_engine= MEMORY;
alter table mysql.slow_log engine=ndb;
ERROR HY000: This storage engine cannot be used for log tables"
alter table mysql.slow_log engine=innodb;
......@@ -177,6 +179,7 @@ alter table mysql.slow_log engine=archive;
ERROR HY000: This storage engine cannot be used for log tables"
alter table mysql.slow_log engine=blackhole;
ERROR HY000: This storage engine cannot be used for log tables"
set storage_engine= @save_storage_engine;
drop table mysql.slow_log;
drop table mysql.general_log;
drop table mysql.general_log;
......
......@@ -10,9 +10,7 @@ ALTER LOGFILE GROUP lg1
ADD UNDOFILE 'undofile02.dat'
INITIAL_SIZE = 4M
ENGINE=XYZ;
Warnings:
Error 1286 Unknown table engine 'XYZ'
Error 1466 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP'
ERROR 42000: Unknown table engine 'XYZ'
CREATE TABLESPACE ts1
ADD DATAFILE 'datafile.dat'
USE LOGFILE GROUP lg1
......
......@@ -54,7 +54,7 @@ create table t1 (a int)
engine = x
partition by key (a);
Warnings:
Error 1286 Unknown table engine 'x'
Warning 1266 Using storage engine MyISAM for table 't1'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
......@@ -66,8 +66,7 @@ engine = innodb
partition by list (a)
(partition p0 values in (0));
alter table t1 engine = x;
Warnings:
Error 1286 Unknown table engine 'x'
ERROR 42000: Unknown table engine 'x'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
......
......@@ -303,8 +303,9 @@ prepare stmt4 from ' show variables like ''sql_mode'' ';
execute stmt4;
Variable_name Value
sql_mode
prepare stmt4 from ' show engine bdb logs ';
prepare stmt4 from ' show engine myisam logs ';
execute stmt4;
Type Name Status
prepare stmt4 from ' show grants for user ';
prepare stmt4 from ' show create table t2 ';
prepare stmt4 from ' show master status ';
......
......@@ -236,7 +236,7 @@ net_buffer_length 1024
net_read_timeout 300
net_retry_count 10
net_write_timeout 200
select * from information_schema.global_variables where variable_name like 'net_%';
select * from information_schema.global_variables where variable_name like 'net_%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
NET_BUFFER_LENGTH 1024
NET_READ_TIMEOUT 300
......@@ -248,7 +248,7 @@ net_buffer_length 2048
net_read_timeout 600
net_retry_count 10
net_write_timeout 500
select * from information_schema.session_variables where variable_name like 'net_%';
select * from information_schema.session_variables where variable_name like 'net_%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
NET_BUFFER_LENGTH 2048
NET_READ_TIMEOUT 600
......@@ -261,7 +261,7 @@ net_buffer_length 1024
net_read_timeout 900
net_retry_count 10
net_write_timeout 1000
select * from information_schema.global_variables where variable_name like 'net_%';
select * from information_schema.global_variables where variable_name like 'net_%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
NET_BUFFER_LENGTH 1024
NET_READ_TIMEOUT 900
......@@ -273,7 +273,7 @@ net_buffer_length 7168
net_read_timeout 600
net_retry_count 10
net_write_timeout 500
select * from information_schema.session_variables where variable_name like 'net_%';
select * from information_schema.session_variables where variable_name like 'net_%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
NET_BUFFER_LENGTH 7168
NET_READ_TIMEOUT 600
......@@ -314,7 +314,7 @@ query_prealloc_size 8192
range_alloc_block_size 2048
transaction_alloc_block_size 8192
transaction_prealloc_size 4096
select * from information_schema.session_variables where variable_name like '%alloc%';
select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
QUERY_ALLOC_BLOCK_SIZE 8192
QUERY_PREALLOC_SIZE 8192
......@@ -336,7 +336,7 @@ query_prealloc_size 18432
range_alloc_block_size 16384
transaction_alloc_block_size 19456
transaction_prealloc_size 20480
select * from information_schema.session_variables where variable_name like '%alloc%';
select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
QUERY_ALLOC_BLOCK_SIZE 17408
QUERY_PREALLOC_SIZE 18432
......@@ -353,7 +353,7 @@ query_prealloc_size 8192
range_alloc_block_size 2048
transaction_alloc_block_size 8192
transaction_prealloc_size 4096
select * from information_schema.session_variables where variable_name like '%alloc%';
select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
QUERY_ALLOC_BLOCK_SIZE 8192
QUERY_PREALLOC_SIZE 8192
......@@ -881,7 +881,7 @@ ssl_capath #
ssl_cert #
ssl_cipher #
ssl_key #
select * from information_schema.session_variables where variable_name like 'ssl%';
select * from information_schema.session_variables where variable_name like 'ssl%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
SSL_CA #
SSL_CAPATH #
......
......@@ -252,6 +252,8 @@ set global general_log='OFF';
set global slow_query_log='OFF';
# check that alter table doesn't work for other engines
set @save_storage_engine= @@session.storage_engine;
set storage_engine= MEMORY;
--error ER_UNSUPORTED_LOG_ENGINE
alter table mysql.slow_log engine=ndb;
--error ER_UNSUPORTED_LOG_ENGINE
......@@ -260,6 +262,7 @@ alter table mysql.slow_log engine=innodb;
alter table mysql.slow_log engine=archive;
--error ER_UNSUPORTED_LOG_ENGINE
alter table mysql.slow_log engine=blackhole;
set storage_engine= @save_storage_engine;
drop table mysql.slow_log;
drop table mysql.general_log;
......
......@@ -21,6 +21,7 @@ INITIAL_SIZE 16M
UNDO_BUFFER_SIZE = 1M
ENGINE=MYISAM;
--error ER_UNKNOWN_STORAGE_ENGINE
ALTER LOGFILE GROUP lg1
ADD UNDOFILE 'undofile02.dat'
INITIAL_SIZE = 4M
......
......@@ -71,6 +71,7 @@ engine = innodb
partition by list (a)
(partition p0 values in (0));
--error ER_UNKNOWN_STORAGE_ENGINE
alter table t1 engine = x;
show create table t1;
drop table t1;
......
......@@ -321,14 +321,8 @@ prepare stmt4 from ' show status like ''Threads_running'' ';
execute stmt4;
prepare stmt4 from ' show variables like ''sql_mode'' ';
execute stmt4;
# The output depends on the bdb being enabled and on the history
# history (actions of the bdb engine).
# That is the reason why, we switch the output here off.
# (The real output will be tested in ps_6bdb.test)
--disable_result_log
prepare stmt4 from ' show engine bdb logs ';
prepare stmt4 from ' show engine myisam logs ';
execute stmt4;
--enable_result_log
prepare stmt4 from ' show grants for user ';
prepare stmt4 from ' show create table t2 ';
prepare stmt4 from ' show master status ';
......
......@@ -151,14 +151,14 @@ set global net_retry_count=10, session net_retry_count=10;
set global net_buffer_length=1024, net_write_timeout=200, net_read_timeout=300;
set session net_buffer_length=2048, net_write_timeout=500, net_read_timeout=600;
show global variables like 'net_%';
select * from information_schema.global_variables where variable_name like 'net_%';
select * from information_schema.global_variables where variable_name like 'net_%' order by 1;
show session variables like 'net_%';
select * from information_schema.session_variables where variable_name like 'net_%';
select * from information_schema.session_variables where variable_name like 'net_%' order by 1;
set session net_buffer_length=8000, global net_read_timeout=900, net_write_timeout=1000;
show global variables like 'net_%';
select * from information_schema.global_variables where variable_name like 'net_%';
select * from information_schema.global_variables where variable_name like 'net_%' order by 1;
show session variables like 'net_%';
select * from information_schema.session_variables where variable_name like 'net_%';
select * from information_schema.session_variables where variable_name like 'net_%' order by 1;
set net_buffer_length=1;
show variables like 'net_buffer_length';
select * from information_schema.session_variables where variable_name like 'net_buffer_length';
......@@ -175,7 +175,7 @@ set @@rand_seed1=10000000,@@rand_seed2=1000000;
select ROUND(RAND(),5);
show variables like '%alloc%';
select * from information_schema.session_variables where variable_name like '%alloc%';
select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
set @@range_alloc_block_size=1024*16;
set @@query_alloc_block_size=1024*17+2;
set @@query_prealloc_size=1024*18;
......@@ -183,12 +183,12 @@ set @@transaction_alloc_block_size=1024*20-1;
set @@transaction_prealloc_size=1024*21-1;
select @@query_alloc_block_size;
show variables like '%alloc%';
select * from information_schema.session_variables where variable_name like '%alloc%';
select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
set @@range_alloc_block_size=default;
set @@query_alloc_block_size=default, @@query_prealloc_size=default;
set transaction_alloc_block_size=default, @@transaction_prealloc_size=default;
show variables like '%alloc%';
select * from information_schema.session_variables where variable_name like '%alloc%';
select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
#
# Bug #10904 Illegal mix of collations between
......@@ -669,7 +669,7 @@ select @@ssl_ca, @@ssl_capath, @@ssl_cert, @@ssl_cipher, @@ssl_key;
--replace_column 2 #
show variables like 'ssl%';
--replace_column 2 #
select * from information_schema.session_variables where variable_name like 'ssl%';
select * from information_schema.session_variables where variable_name like 'ssl%' order by 1;
#
# Bug #19616: make log_queries_not_using_indexes available in SHOW VARIABLES
......
--loose-skip-ndb
--loose-skip-plugin-ndbcluster
......@@ -26,9 +26,10 @@
Initiate dynamic array
SYNOPSIS
init_dynamic_array()
init_dynamic_array2()
array Pointer to an array
element_size Size of element
init_buffer Initial buffer pointer
init_alloc Number of initial elements
alloc_increment Increment for adding new elements
......@@ -36,14 +37,15 @@
init_dynamic_array() initiates array and allocate space for
init_alloc eilements.
Array is usable even if space allocation failed.
Static buffers must begin immediately after the array structure.
RETURN VALUE
TRUE my_malloc_ci() failed
FALSE Ok
*/
my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
uint init_alloc,
my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size,
void *init_buffer, uint init_alloc,
uint alloc_increment CALLER_INFO_PROTO)
{
DBUG_ENTER("init_dynamic_array");
......@@ -56,10 +58,14 @@ my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
if (!init_alloc)
init_alloc=alloc_increment;
else
init_buffer= 0;
array->elements=0;
array->max_element=init_alloc;
array->alloc_increment=alloc_increment;
array->size_of_element=element_size;
if ((array->buffer= init_buffer))
DBUG_RETURN(FALSE);
if (!(array->buffer=(char*) my_malloc_ci(element_size*init_alloc,MYF(MY_WME))))
{
array->max_element=0;
......@@ -68,6 +74,14 @@ my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
DBUG_RETURN(FALSE);
}
my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
uint init_alloc,
uint alloc_increment CALLER_INFO_PROTO)
{
/* placeholder to preserve ABI */
return my_init_dynamic_array_ci(array, element_size, init_alloc,
alloc_increment);
}
/*
Insert element at the end of array. Allocate memory if needed.
......@@ -121,6 +135,21 @@ byte *alloc_dynamic(DYNAMIC_ARRAY *array)
if (array->elements == array->max_element)
{
char *new_ptr;
if (array->buffer == (char *)(array + 1))
{
/*
In this senerio, the buffer is statically preallocated,
so we have to create an all-new malloc since we overflowed
*/
if (!(new_ptr= (char *) my_malloc((array->max_element+
array->alloc_increment) *
array->size_of_element,
MYF(MY_WME))))
return 0;
memcpy(new_ptr, array->buffer,
array->elements * array->size_of_element);
}
else
if (!(new_ptr=(char*) my_realloc(array->buffer,(array->max_element+
array->alloc_increment)*
array->size_of_element,
......@@ -180,6 +209,20 @@ my_bool set_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
char *new_ptr;
size=(idx+array->alloc_increment)/array->alloc_increment;
size*= array->alloc_increment;
if (array->buffer == (char *)(array + 1))
{
/*
In this senerio, the buffer is statically preallocated,
so we have to create an all-new malloc since we overflowed
*/
if (!(new_ptr= (char *) my_malloc(size *
array->size_of_element,
MYF(MY_WME))))
return 0;
memcpy(new_ptr, array->buffer,
array->elements * array->size_of_element);
}
else
if (!(new_ptr=(char*) my_realloc(array->buffer,size*
array->size_of_element,
MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
......@@ -230,6 +273,12 @@ void get_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
void delete_dynamic(DYNAMIC_ARRAY *array)
{
/*
Just mark as empty if we are using a static buffer
*/
if (array->buffer == (char *)(array + 1))
array->elements= 0;
else
if (array->buffer)
{
my_free(array->buffer,MYF(MY_WME));
......@@ -269,6 +318,12 @@ void freeze_size(DYNAMIC_ARRAY *array)
{
uint elements=max(array->elements,1);
/*
Do nothing if we are using a static buffer
*/
if (array->buffer == (char *)(array + 1))
return;
if (array->buffer && array->max_element != elements)
{
array->buffer=(char*) my_realloc(array->buffer,
......
......@@ -315,6 +315,10 @@ my_bool my_hash_insert(HASH *info,const byte *record)
LINT_INIT(gpos); LINT_INIT(gpos2);
LINT_INIT(ptr_to_rec); LINT_INIT(ptr_to_rec2);
if (HASH_UNIQUE & info->flags &&
hash_search(info, hash_key(info, record, &idx, 1), idx))
return(TRUE); /* Duplicate entry */
flag=0;
if (!(empty=(HASH_LINK*) alloc_dynamic(&info->array)))
return(TRUE); /* No more memory */
......@@ -530,6 +534,19 @@ my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length)
uint idx,new_index,new_pos_index,blength,records,empty;
HASH_LINK org_link,*data,*previous,*pos;
DBUG_ENTER("hash_update");
if (HASH_UNIQUE & hash->flags)
{
HASH_SEARCH_STATE state;
byte *found, *new_key= hash_key(hash, record, &idx, 1);
if ((found= hash_first(hash, new_key, idx, &state)))
do
{
if (found != record)
DBUG_RETURN(1); /* Duplicate entry */
}
while ((found= hash_next(hash, new_key, idx, &state)));
}
data=dynamic_element(&hash->array,0,HASH_LINK*);
blength=hash->blength; records=hash->records;
......
......@@ -58,6 +58,13 @@ char *disabled_my_option= (char*) "0";
my_bool my_getopt_print_errors= 1;
/*
This is a flag that can be set in client programs. 1 means that
my_getopt will skip over options it does not know how to handle.
*/
my_bool my_getopt_skip_unknown= 0;
static void default_reporter(enum loglevel level,
const char *format, ...)
{
......@@ -110,6 +117,7 @@ int handle_options(int *argc, char ***argv,
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
{
char **first= pos;
char *cur_arg= *pos;
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
{
......@@ -259,6 +267,19 @@ int handle_options(int *argc, char ***argv,
}
if (!opt_found)
{
if (my_getopt_skip_unknown)
{
/*
preserve all the components of this unknown option, this may
occurr when the user provides options like: "-O foo" or
"--set-variable foo" (note that theres a space in there)
Generally, these kind of options are to be avoided
*/
do {
(*argv)[argvpos++]= *first++;
} while (first <= pos);
continue;
}
if (must_be_var)
{
if (my_getopt_print_errors)
......@@ -596,6 +617,15 @@ static int setval(const struct my_option *opts, gptr *value, char *argument,
if (!(*((char**) result_pos)= my_strdup(argument, MYF(MY_WME))))
return EXIT_OUT_OF_MEMORY;
break;
case GET_ENUM:
if (((*(int*)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0)
return EXIT_ARGUMENT_INVALID;
break;
case GET_SET:
*((ulonglong*)result_pos)= find_typeset(argument, opts->typelib, &err);
if (err)
return EXIT_ARGUMENT_INVALID;
break;
default: /* dummy default to avoid compiler warnings */
break;
}
......@@ -788,6 +818,7 @@ static void init_one_value(const struct my_option *option, gptr *variable,
*((int*) variable)= (int) value;
break;
case GET_UINT:
case GET_ENUM:
*((uint*) variable)= (uint) value;
break;
case GET_LONG:
......@@ -800,6 +831,7 @@ static void init_one_value(const struct my_option *option, gptr *variable,
*((longlong*) variable)= (longlong) value;
break;
case GET_ULL:
case GET_SET:
*((ulonglong*) variable)= (ulonglong) value;
break;
default: /* dummy default to avoid compiler warnings */
......@@ -928,7 +960,8 @@ void my_print_help(const struct my_option *options)
void my_print_variables(const struct my_option *options)
{
uint name_space= 34, length;
uint name_space= 34, length, nr;
ulonglong bit, llvalue;
char buff[255];
const struct my_option *optp;
......@@ -946,6 +979,21 @@ void my_print_variables(const struct my_option *options)
for (; length < name_space; length++)
putchar(' ');
switch ((optp->var_type & GET_TYPE_MASK)) {
case GET_SET:
if (!(llvalue= *(ulonglong*) value))
printf("%s\n", "(No default value)");
else
for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
{
if (!(bit & llvalue))
continue;
llvalue&= ~bit;
printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr));
}
break;
case GET_ENUM:
printf("%s\n", get_type(optp->typelib, *(uint*) value));
break;
case GET_STR:
case GET_STR_ALLOC: /* fall through */
printf("%s\n", *((char**) value) ? *((char**) value) :
......
......@@ -120,6 +120,54 @@ const char *get_type(TYPELIB *typelib, uint nr)
}
static const char field_separator=',';
/*
Create an integer value to represent the supplied comma-seperated
string where each string in the TYPELIB denotes a bit position.
SYNOPSIS
find_typeset()
x string to decompose
lib TYPELIB (struct of pointer to values + count)
err index (not char position) of string element which was not
found or 0 if there was no error
RETURN
a integer representation of the supplied string
*/
my_ulonglong find_typeset(my_string x, TYPELIB *lib, int *err)
{
my_ulonglong result;
int find;
my_string i;
DBUG_ENTER("find_set");
DBUG_PRINT("enter",("x: '%s' lib: 0x%lx", x, (long) lib));
if (!lib->count)
{
DBUG_PRINT("exit",("no count"));
DBUG_RETURN(0);
}
result= 0;
*err= 0;
while (*x)
{
(*err)++;
i= x;
while (*x && *x != field_separator) x++;
if (*x)
*x++= 0;
if ((find= find_type(i, lib, 2) - 1) < 0)
DBUG_RETURN(0);
result|= (ULL(1) << find);
}
*err= 0;
DBUG_RETURN(result);
} /* find_set */
/*
Create a copy of a specified TYPELIB structure.
......
......@@ -2629,7 +2629,7 @@ int ha_ndbcluster::write_row(byte *record)
DBUG_RETURN(peek_res);
}
statistic_increment(thd->status_var.ha_write_count, &LOCK_status);
ha_statistic_increment(&SSV::ha_write_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
......@@ -2849,7 +2849,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data)
DBUG_RETURN(peek_res);
}
statistic_increment(thd->status_var.ha_update_count, &LOCK_status);
ha_statistic_increment(&SSV::ha_update_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
{
table->timestamp_field->set_time();
......@@ -3016,7 +3016,7 @@ int ha_ndbcluster::delete_row(const byte *record)
DBUG_ENTER("delete_row");
m_write_op= TRUE;
statistic_increment(thd->status_var.ha_delete_count,&LOCK_status);
ha_statistic_increment(&SSV::ha_delete_count);
m_rows_changed++;
if (m_use_partition_function &&
......@@ -3372,7 +3372,7 @@ int ha_ndbcluster::index_read_idx(byte *buf, uint index_no,
const byte *key, uint key_len,
enum ha_rkey_function find_flag)
{
statistic_increment(current_thd->status_var.ha_read_key_count, &LOCK_status);
ha_statistic_increment(&SSV::ha_read_key_count);
DBUG_ENTER("ha_ndbcluster::index_read_idx");
DBUG_PRINT("enter", ("index_no: %u, key_len: %u", index_no, key_len));
close_scan();
......@@ -3384,8 +3384,7 @@ int ha_ndbcluster::index_read_idx(byte *buf, uint index_no,
int ha_ndbcluster::index_next(byte *buf)
{
DBUG_ENTER("ha_ndbcluster::index_next");
statistic_increment(current_thd->status_var.ha_read_next_count,
&LOCK_status);
ha_statistic_increment(&SSV::ha_read_next_count);
DBUG_RETURN(next_result(buf));
}
......@@ -3393,8 +3392,7 @@ int ha_ndbcluster::index_next(byte *buf)
int ha_ndbcluster::index_prev(byte *buf)
{
DBUG_ENTER("ha_ndbcluster::index_prev");
statistic_increment(current_thd->status_var.ha_read_prev_count,
&LOCK_status);
ha_statistic_increment(&SSV::ha_read_prev_count);
DBUG_RETURN(next_result(buf));
}
......@@ -3402,8 +3400,7 @@ int ha_ndbcluster::index_prev(byte *buf)
int ha_ndbcluster::index_first(byte *buf)
{
DBUG_ENTER("ha_ndbcluster::index_first");
statistic_increment(current_thd->status_var.ha_read_first_count,
&LOCK_status);
ha_statistic_increment(&SSV::ha_read_first_count);
// Start the ordered index scan and fetch the first row
// Only HA_READ_ORDER indexes get called by index_first
......@@ -3414,7 +3411,7 @@ int ha_ndbcluster::index_first(byte *buf)
int ha_ndbcluster::index_last(byte *buf)
{
DBUG_ENTER("ha_ndbcluster::index_last");
statistic_increment(current_thd->status_var.ha_read_last_count,&LOCK_status);
ha_statistic_increment(&SSV::ha_read_last_count);
DBUG_RETURN(ordered_index_scan(0, 0, TRUE, TRUE, buf, NULL));
}
......@@ -3600,8 +3597,7 @@ int ha_ndbcluster::rnd_end()
int ha_ndbcluster::rnd_next(byte *buf)
{
DBUG_ENTER("rnd_next");
statistic_increment(current_thd->status_var.ha_read_rnd_next_count,
&LOCK_status);
ha_statistic_increment(&SSV::ha_read_rnd_next_count);
if (!m_active_cursor)
DBUG_RETURN(full_table_scan(buf));
......@@ -3619,8 +3615,7 @@ int ha_ndbcluster::rnd_next(byte *buf)
int ha_ndbcluster::rnd_pos(byte *buf, byte *pos)
{
DBUG_ENTER("rnd_pos");
statistic_increment(current_thd->status_var.ha_read_rnd_count,
&LOCK_status);
ha_statistic_increment(&SSV::ha_read_rnd_count);
// The primary key for the record is stored in pos
// Perform a pk_read using primary key "index"
{
......@@ -6743,7 +6738,7 @@ static int ndbcluster_init(void *p)
{
handlerton *h= ndbcluster_hton;
h->state= have_ndbcluster;
h->state= SHOW_OPTION_YES;
h->db_type= DB_TYPE_NDBCLUSTER;
h->close_connection= ndbcluster_close_connection;
h->commit= ndbcluster_commit;
......@@ -6765,9 +6760,6 @@ static int ndbcluster_init(void *p)
h->table_exists_in_engine= ndbcluster_table_exists_in_engine;
}
if (have_ndbcluster != SHOW_OPTION_YES)
DBUG_RETURN(0); // nothing else to do
// Initialize ndb interface
ndb_init_internal();
......@@ -6883,7 +6875,6 @@ ndbcluster_init_error:
if (g_ndb_cluster_connection)
delete g_ndb_cluster_connection;
g_ndb_cluster_connection= NULL;
have_ndbcluster= SHOW_OPTION_DISABLED; // If we couldn't use handler
ndbcluster_hton->state= SHOW_OPTION_DISABLED; // If we couldn't use handler
DBUG_RETURN(TRUE);
......@@ -10220,10 +10211,6 @@ ndbcluster_show_status(handlerton *hton, THD* thd, stat_print_fn *stat_print,
uint buflen;
DBUG_ENTER("ndbcluster_show_status");
if (have_ndbcluster != SHOW_OPTION_YES)
{
DBUG_RETURN(FALSE);
}
if (stat_type != HA_ENGINE_STATUS)
{
DBUG_RETURN(FALSE);
......
......@@ -1987,6 +1987,8 @@ bool ha_partition::create_handler_file(const char *name)
void ha_partition::clear_handler_file()
{
if (m_engine_array)
plugin_unlock_list(NULL, m_engine_array, m_tot_parts);
my_free((char*) m_file_buffer, MYF(MY_ALLOW_ZERO_PTR));
my_free((char*) m_engine_array, MYF(MY_ALLOW_ZERO_PTR));
m_file_buffer= NULL;
......@@ -2009,6 +2011,7 @@ bool ha_partition::create_handlers(MEM_ROOT *mem_root)
{
uint i;
uint alloc_len= (m_tot_parts + 1) * sizeof(handler*);
handlerton *hton0;
DBUG_ENTER("create_handlers");
if (!(m_file= (handler **) alloc_root(mem_root, alloc_len)))
......@@ -2017,19 +2020,21 @@ bool ha_partition::create_handlers(MEM_ROOT *mem_root)
bzero((char*) m_file, alloc_len);
for (i= 0; i < m_tot_parts; i++)
{
handlerton *hton= plugin_data(m_engine_array[i], handlerton*);
if (!(m_file[i]= get_new_handler(table_share, mem_root,
m_engine_array[i])))
hton)))
DBUG_RETURN(TRUE);
DBUG_PRINT("info", ("engine_type: %u", m_engine_array[i]->db_type));
DBUG_PRINT("info", ("engine_type: %u", hton->db_type));
}
/* For the moment we only support partition over the same table engine */
if (m_engine_array[0] == myisam_hton)
hton0= plugin_data(m_engine_array[0], handlerton*);
if (hton0 == myisam_hton)
{
DBUG_PRINT("info", ("MyISAM"));
m_myisam= TRUE;
}
/* INNODB may not be compiled in... */
else if (ha_legacy_type(m_engine_array[0]) == DB_TYPE_INNODB)
else if (ha_legacy_type(hton0) == DB_TYPE_INNODB)
{
DBUG_PRINT("info", ("InnoDB"));
m_innodb= TRUE;
......@@ -2160,8 +2165,7 @@ bool ha_partition::get_from_handler_file(const char *name, MEM_ROOT *mem_root)
m_tot_parts= uint4korr((file_buffer) + 8);
DBUG_PRINT("info", ("No of parts = %u", m_tot_parts));
tot_partition_words= (m_tot_parts + 3) / 4;
if (!(engine_array= (handlerton **) my_malloc(m_tot_parts * sizeof(handlerton*),MYF(0))))
goto err2;
engine_array= (handlerton **) my_alloca(m_tot_parts * sizeof(handlerton*));
for (i= 0; i < m_tot_parts; i++)
engine_array[i]= ha_resolve_by_legacy_type(current_thd,
(enum legacy_db_type)
......@@ -2174,7 +2178,14 @@ bool ha_partition::get_from_handler_file(const char *name, MEM_ROOT *mem_root)
VOID(my_close(file, MYF(0)));
m_file_buffer= file_buffer; // Will be freed in clear_handler_file()
m_name_buffer_ptr= name_buffer_ptr;
m_engine_array= engine_array;
if (!(m_engine_array= (plugin_ref*)
my_malloc(m_tot_parts * sizeof(plugin_ref), MYF(MY_WME))))
goto err2;
for (i= 0; i < m_tot_parts; i++)
m_engine_array[i]= ha_lock_engine(NULL, engine_array[i]);
if (!m_file && create_handlers(mem_root))
{
clear_handler_file();
......
......@@ -27,6 +27,7 @@ enum partition_keywords
The partition implements the minimum of what you will probably need.
*/
#ifdef NOT_USED
typedef struct st_partition_share
{
char *table_name;
......@@ -34,6 +35,7 @@ typedef struct st_partition_share
pthread_mutex_t mutex;
THR_LOCK lock;
} PARTITION_SHARE;
#endif
#define PARTITION_BYTES_IN_POS 2
......@@ -54,7 +56,7 @@ private:
uint m_open_test_lock; // Open test_if_locked
char *m_file_buffer; // Buffer with names
char *m_name_buffer_ptr; // Pointer to first partition name
handlerton **m_engine_array; // Array of types of the handlers
plugin_ref *m_engine_array; // Array of types of the handlers
handler **m_file; // Array of references to handler inst.
uint m_file_tot_parts; // Debug
handler **m_new_file; // Array of references to new handlers
......@@ -130,7 +132,9 @@ private:
Variables for lock structures.
*/
THR_LOCK_DATA lock; /* MySQL lock */
#ifdef NOT_USED
PARTITION_SHARE *share; /* Shared lock info */
#endif
public:
virtual void set_part_info(partition_info *part_info)
......
This diff is collapsed.
......@@ -876,6 +876,8 @@ public:
class handler :public Sql_alloc
{
friend class ha_partition;
friend int ha_delete_table(THD*,handlerton*,const char*,const char*,
const char*,bool);
protected:
struct st_table_share *table_share; /* The table definition */
......@@ -894,7 +896,12 @@ class handler :public Sql_alloc
virtual int rnd_init(bool scan) =0;
virtual int rnd_end() { return 0; }
virtual ulonglong table_flags(void) const =0;
void ha_statistic_increment(ulong SSV::*offset) const;
enum enum_tx_isolation ha_tx_isolation(void) const;
uint ha_sql_command(void) const;
void **ha_data(void) const;
THD *ha_thd(void) const;
ha_rows estimation_rows_to_insert;
virtual void start_bulk_insert(ha_rows rows) {}
......@@ -1626,9 +1633,9 @@ extern ulong total_ha, total_ha_2pc;
/* lookups */
handlerton *ha_default_handlerton(THD *thd);
handlerton *ha_resolve_by_name(THD *thd, const LEX_STRING *name);
plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name);
plugin_ref ha_lock_engine(THD *thd, handlerton *hton);
handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
const char *ha_get_storage_engine(enum legacy_db_type db_type);
handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
handlerton *db_type);
handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
......
......@@ -4887,7 +4887,7 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
component_name= &component; // Empty string
}
if (!(var= find_sys_var(base_name->str, base_name->length)))
if (!(var= find_sys_var(thd, base_name->str, base_name->length)))
return 0;
if (component.str)
{
......
......@@ -2469,7 +2469,7 @@ bool Item_sum_count_distinct::setup(THD *thd)
table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows
table->no_rows=1;
if (table->s->db_type == heap_hton)
if (table->s->db_type() == heap_hton)
{
/*
No blobs, otherwise it would have been MyISAM: set up a compare
......
......@@ -546,11 +546,6 @@ inline THD *_current_thd(void)
}
#define current_thd _current_thd()
/* below functions are required for plugins as THD class is opaque */
my_bool thd_in_lock_tables(const THD *thd);
my_bool thd_tablespace_op(const THD *thd);
const char *thd_proc_info(THD *thd, const char *info);
void **thd_ha_data(const THD *thd, const struct handlerton *hton);
/*
External variables
......@@ -1098,6 +1093,7 @@ int add_status_vars(SHOW_VAR *list);
void remove_status_vars(SHOW_VAR *list);
void init_status_vars();
void free_status_vars();
void reset_status_vars();
/* information schema */
extern LEX_STRING information_schema_name;
......@@ -1659,6 +1655,7 @@ extern pthread_mutex_t LOCK_server_started;
extern pthread_cond_t COND_server_started;
extern int mysqld_server_started;
extern rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
extern rw_lock_t LOCK_system_variables_hash;
extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager;
extern pthread_cond_t COND_global_read_lock;
extern pthread_attr_t connection_attrib;
......@@ -1667,7 +1664,7 @@ extern I_List<NAMED_LIST> key_caches;
extern MY_BITMAP temp_pool;
extern String my_empty_string;
extern const String my_null_string;
extern SHOW_VAR init_vars[], status_vars[], internal_vars[];
extern SHOW_VAR status_vars[];
extern struct system_variables global_system_variables;
extern struct system_variables max_system_variables;
extern struct system_status_var global_status_var;
......@@ -1690,11 +1687,6 @@ extern TYPELIB log_output_typelib;
/* optional things, have_* variables */
extern SHOW_COMP_OPTION have_innodb;
extern SHOW_COMP_OPTION have_csv_db;
extern SHOW_COMP_OPTION have_ndbcluster;
extern SHOW_COMP_OPTION have_partition_db;
extern handlerton *partition_hton;
extern handlerton *myisam_hton;
extern handlerton *heap_hton;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -868,7 +868,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
/* If it is a temporary table, close and regenerate it */
if (!dont_send_ok && (table= find_temporary_table(thd, table_list)))
{
handlerton *table_type= table->s->db_type;
handlerton *table_type= table->s->db_type();
TABLE_SHARE *share= table->s;
if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE))
goto trunc_by_del;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment