Commit ebcc7b5a authored by monty@mashka.mysql.fi's avatar monty@mashka.mysql.fi

Support for variables with components

Added framework to create/drop and manager buffers for multiple key caches
parent bad00c38
......@@ -53,7 +53,7 @@ extern int handle_options (int *argc, char ***argv,
char *));
extern void my_print_help(const struct my_option *options);
extern void my_print_variables(const struct my_option *options);
extern void my_getopt_register_get_addr(gptr* (*func_addr)(char *, uint,
extern void my_getopt_register_get_addr(gptr* (*func_addr)(const char *, uint,
const struct my_option *));
ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp);
......
......@@ -501,6 +501,12 @@ my_off_t my_b_append_tell(IO_CACHE* info);
#define my_b_bytes_in_cache(info) (uint) (*(info)->current_end - \
*(info)->current_pos)
/* key_cache_variables */
typedef struct st_keycache
{
ulonglong size;
} KEY_CACHE;
#include <my_alloc.h>
/* Prototypes for mysys and my_func functions */
......
......@@ -286,4 +286,5 @@
#define ER_REVOKE_GRANTS 1267
#define ER_CANT_AGGREGATE_3COLLATIONS 1268
#define ER_CANT_AGGREGATE_NCOLLATIONS 1269
#define ER_ERROR_MESSAGES 270
#define ER_VARIABLE_IS_NOT_STRUCT 1270
#define ER_ERROR_MESSAGES 271
SET @save_key_buffer=@@key_buffer_size;
SELECT @@key_buffer_size, @@small.key_buffer_size;
@@key_buffer_size @@small.key_buffer_size
2097152 131072
SET @@global.key_buffer_size=16*1024*1024;
SET @@global.default.key_buffer_size=16*1024*1024;
SET @@global.default.key_buffer_size=16*1024*1024;
SET @@global.small.key_buffer_size=1*1024*1024;
SET @@global.medium.key_buffer_size=4*1024*1024;
SET @@global.medium.key_buffer_size=0;
SET @@global.medium.key_buffer_size=0;
SHOW VARIABLES like "key_buffer_size";
Variable_name Value
key_buffer_size 16777216
SELECT @@key_buffer_size;
@@key_buffer_size
16777216
SELECT @@global.key_buffer_size;
@@global.key_buffer_size
16777216
SELECT @@global.default.key_buffer_size;
@@global.default.key_buffer_size
16777216
SELECT @@global.default.`key_buffer_size`;
@@global.default.key_buffer_size
16777216
SELECT @@global.`default`.`key_buffer_size`;
@@global.default.key_buffer_size
16777216
SELECT @@`default`.key_buffer_size;
@@default.key_buffer_size
16777216
SELECT @@small.key_buffer_size;
@@small.key_buffer_size
1048576
SELECT @@medium.key_buffer_size;
@@medium.key_buffer_size
4194304
SET @@global.key_buffer_size=@save_key_buffer;
SELECT @@default.key_buffer_size;
ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'default.key_buffer_size' at line 1
SELECT @@skr.table_type="test";
ERROR HY000: Variable 'table_type' is not a variable component (Can't be used as XXXX.variable_name)
......@@ -37,7 +37,7 @@ delete from t1 where b="test" limit 1;
delete from t1 where a+0=1 limit 2;
SET MAX_JOIN_SIZE=2;
SELECT @@MAX_JOIN_SIZE, @@SQL_BIG_SELECTS;
@@max_join_size @@sql_big_selects
@@MAX_JOIN_SIZE @@SQL_BIG_SELECTS
2 0
insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a");
SELECT * from t1;
......
......@@ -77,7 +77,7 @@ select last_insert_id(345);
last_insert_id(345)
345
select @@IDENTITY,last_insert_id(), @@identity;
@@identity last_insert_id() @@identity
@@IDENTITY last_insert_id() @@identity
345 345 345
set big_tables=OFF, big_tables=ON, big_tables=0, big_tables=1, big_tables="OFF", big_tables="ON";
set global concurrent_insert=ON;
......
--key_buffer_size=2M --small.key_buffer_size=256K --small.key_buffer_size=128K
#
# Test of key cache
#
SET @save_key_buffer=@@key_buffer_size;
SELECT @@key_buffer_size, @@small.key_buffer_size;
# Change default key cache size
SET @@global.key_buffer_size=16*1024*1024;
SET @@global.default.key_buffer_size=16*1024*1024;
SET @@global.default.key_buffer_size=16*1024*1024;
SET @@global.small.key_buffer_size=1*1024*1024;
SET @@global.medium.key_buffer_size=4*1024*1024;
# Drop buffer
SET @@global.medium.key_buffer_size=0;
# Test double drop
SET @@global.medium.key_buffer_size=0;
# Print key buffer with different syntaxes
SHOW VARIABLES like "key_buffer_size";
SELECT @@key_buffer_size;
SELECT @@global.key_buffer_size;
SELECT @@global.default.key_buffer_size;
SELECT @@global.default.`key_buffer_size`;
SELECT @@global.`default`.`key_buffer_size`;
SELECT @@`default`.key_buffer_size;
SELECT @@small.key_buffer_size;
SELECT @@medium.key_buffer_size;
SET @@global.key_buffer_size=@save_key_buffer;
#
# Errors
#
--error 1064
SELECT @@default.key_buffer_size;
--error 1270
SELECT @@skr.table_type="test";
......@@ -32,7 +32,7 @@ static longlong getopt_ll(char *arg, const struct my_option *optp, int *err);
static ulonglong getopt_ull(char *arg, const struct my_option *optp,
int *err);
static void init_variables(const struct my_option *options);
static int setval(const struct my_option *opts, char *argument,
static int setval(const struct my_option *opts, gptr *value, char *argument,
my_bool set_maximum_value);
static char *check_struct_option(char *cur_arg, char *key_name);
......@@ -68,9 +68,9 @@ my_bool my_getopt_print_errors= 1;
one. Call function 'get_one_option()' once for each option.
*/
static gptr* (*getopt_get_addr)(char *, uint, const struct my_option *);
static gptr* (*getopt_get_addr)(const char *, uint, const struct my_option *);
void my_getopt_register_get_addr(gptr* (*func_addr)(char *, uint,
void my_getopt_register_get_addr(gptr* (*func_addr)(const char *, uint,
const struct my_option *))
{
getopt_get_addr= func_addr;
......@@ -395,7 +395,8 @@ int handle_options(int *argc, char ***argv,
/* the other loop will break, because *optend + 1 == 0 */
}
}
if ((error= setval(optp, argument, set_maximum_value)))
if ((error= setval(optp, optp->value, argument,
set_maximum_value)))
{
fprintf(stderr,
"%s: Error while setting value '%s' to '%s'\n",
......@@ -417,7 +418,7 @@ int handle_options(int *argc, char ***argv,
(*argc)--; /* option handled (short), decrease argument count */
continue;
}
if ((error= setval(optp, argument, set_maximum_value)))
if ((error= setval(optp, value, argument, set_maximum_value)))
{
fprintf(stderr,
"%s: Error while setting value '%s' to '%s'\n",
......@@ -473,13 +474,13 @@ static char *check_struct_option(char *cur_arg, char *key_name)
if (end - ptr > 1)
{
uint len= ptr - cur_arg;
strnmov(key_name, cur_arg, len);
key_name[len]= '\0';
set_if_smaller(len, FN_REFLEN-1);
strmake(key_name, cur_arg, len);
return ++ptr;
}
else
{
key_name= 0;
key_name[0]= 0;
return cur_arg;
}
}
......@@ -491,15 +492,15 @@ static char *check_struct_option(char *cur_arg, char *key_name)
Will set the option value to given value
*/
static int setval(const struct my_option *opts, char *argument,
static int setval(const struct my_option *opts, gptr *value, char *argument,
my_bool set_maximum_value)
{
int err= 0;
if (opts->value && argument)
if (value && argument)
{
gptr *result_pos= ((set_maximum_value) ?
opts->u_max_value : opts->value);
opts->u_max_value : value);
if (!result_pos)
return EXIT_NO_PTR_TO_VARIABLE;
......@@ -692,43 +693,45 @@ static void init_variables(const struct my_option *options)
{
for (; options->name; options++)
{
if (options->value)
gptr *value= (options->var_type & GET_ASK_ADDR ?
(*getopt_get_addr)("", 0, options) : options->value);
if (value)
{
switch ((options->var_type & GET_TYPE_MASK)) {
case GET_BOOL:
if (options->u_max_value)
*((my_bool*) options->u_max_value)= (my_bool) options->max_value;
*((my_bool*) options->value)= (my_bool) options->def_value;
*((my_bool*) value)= (my_bool) options->def_value;
break;
case GET_INT:
if (options->u_max_value)
*((int*) options->u_max_value)= (int) options->max_value;
*((int*) options->value)= (int) options->def_value;
*((int*) value)= (int) options->def_value;
break;
case GET_UINT:
if (options->u_max_value)
*((uint*) options->u_max_value)= (uint) options->max_value;
*((uint*) options->value)= (uint) options->def_value;
*((uint*) value)= (uint) options->def_value;
break;
case GET_LONG:
if (options->u_max_value)
*((long*) options->u_max_value)= (long) options->max_value;
*((long*) options->value)= (long) options->def_value;
*((long*) value)= (long) options->def_value;
break;
case GET_ULONG:
if (options->u_max_value)
*((ulong*) options->u_max_value)= (ulong) options->max_value;
*((ulong*) options->value)= (ulong) options->def_value;
*((ulong*) value)= (ulong) options->def_value;
break;
case GET_LL:
if (options->u_max_value)
*((longlong*) options->u_max_value)= (longlong) options->max_value;
*((longlong*) options->value)= (longlong) options->def_value;
*((longlong*) value)= (longlong) options->def_value;
break;
case GET_ULL:
if (options->u_max_value)
*((ulonglong*) options->u_max_value)= (ulonglong) options->max_value;
*((ulonglong*) options->value)= (ulonglong) options->def_value;
*((ulonglong*) value)= (ulonglong) options->def_value;
break;
default: /* dummy default to avoid compiler warnings */
break;
......@@ -831,7 +834,9 @@ void my_print_variables(const struct my_option *options)
printf("--------------------------------- -----------------------------\n");
for (optp= options; optp->id; optp++)
{
if (optp->value)
gptr *value= (optp->var_type & GET_ASK_ADDR ?
(*getopt_get_addr)("", 0, optp) : optp->value);
if (value)
{
printf("%s", optp->name);
length= strlen(optp->name);
......@@ -840,29 +845,29 @@ void my_print_variables(const struct my_option *options)
switch ((optp->var_type & GET_TYPE_MASK)) {
case GET_STR:
case GET_STR_ALLOC: /* fall through */
printf("%s\n", *((char**) optp->value) ? *((char**) optp->value) :
printf("%s\n", *((char**) value) ? *((char**) value) :
"(No default value)");
break;
case GET_BOOL:
printf("%s\n", *((my_bool*) optp->value) ? "TRUE" : "FALSE");
printf("%s\n", *((my_bool*) value) ? "TRUE" : "FALSE");
break;
case GET_INT:
printf("%d\n", *((int*) optp->value));
printf("%d\n", *((int*) value));
break;
case GET_UINT:
printf("%d\n", *((uint*) optp->value));
printf("%d\n", *((uint*) value));
break;
case GET_LONG:
printf("%lu\n", *((long*) optp->value));
printf("%lu\n", *((long*) value));
break;
case GET_ULONG:
printf("%lu\n", *((ulong*) optp->value));
printf("%lu\n", *((ulong*) value));
break;
case GET_LL:
printf("%s\n", llstr(*((longlong*) optp->value), buff));
printf("%s\n", llstr(*((longlong*) value), buff));
break;
case GET_ULL:
longlong2str(*((ulonglong*) optp->value), buff, 10);
longlong2str(*((ulonglong*) value), buff, 10);
printf("%s\n", buff);
break;
default: /* dummy default to avoid compiler warnings */
......
......@@ -117,7 +117,7 @@ gen_lex_hash.o: gen_lex_hash.cc lex.h
sql_yacc.cc: sql_yacc.yy
sql_yacc.h: sql_yacc.yy
sql_yacc.o: sql_yacc.cc sql_yacc.h
sql_yacc.o: sql_yacc.cc sql_yacc.h $(HEADERS)
@echo "Note: The following compile may take a long time."
@echo "If it fails, re-run configure with --with-low-memory"
$(CXXCOMPILE) $(LM_CFLAGS) -c $<
......
......@@ -2694,21 +2694,61 @@ longlong Item_func_bit_xor::val_int()
System variables
****************************************************************************/
Item *get_system_var(enum_var_type var_type, LEX_STRING name)
/*
Return value of an system variable base[.name] as a constant item
SYNOPSIS
get_system_var()
thd Thread handler
var_type global / session
name Name of base or system variable
component Component.
NOTES
If component.str = 0 then the variable name is in 'name'
RETURN
0 error
# constant item
*/
Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
LEX_STRING component)
{
if (!my_strcasecmp(system_charset_info, name.str, "VERSION"))
if (component.str == 0 &&
!my_strcasecmp(system_charset_info, name.str, "VERSION"))
return new Item_string("@@VERSION", server_version,
(uint) strlen(server_version),
system_charset_info);
THD *thd=current_thd;
Item *item;
sys_var *var;
char buff[MAX_SYS_VAR_LENGTH+3+8], *pos;
char buff[MAX_SYS_VAR_LENGTH*2+4+8], *pos;
LEX_STRING *base_name, *component_name;
if (component.str)
{
base_name= &component;
component_name= &name;
}
else
{
base_name= &name;
component_name= &component; // Empty string
}
if (!(var= find_sys_var(name.str, name.length)))
if (!(var= find_sys_var(base_name->str, base_name->length)))
return 0;
if (!(item=var->item(thd, var_type)))
if (component.str)
{
if (!var->is_struct())
{
net_printf(thd, ER_VARIABLE_IS_NOT_STRUCT, base_name->str);
return 0;
}
}
if (!(item=var->item(thd, var_type, component_name)))
return 0; // Impossible
thd->lex.uncacheable();
buff[0]='@';
......@@ -2718,23 +2758,37 @@ Item *get_system_var(enum_var_type var_type, LEX_STRING name)
pos=strmov(pos,"session.");
else if (var_type == OPT_GLOBAL)
pos=strmov(pos,"global.");
memcpy(pos, var->name, var->name_length+1);
set_if_smaller(component_name->length, MAX_SYS_VAR_LENGTH);
set_if_smaller(base_name->length, MAX_SYS_VAR_LENGTH);
if (component_name->str)
{
memcpy(pos, component_name->str, component_name->length);
pos+= component_name->length;
*pos++= '.';
}
memcpy(pos, base_name->str, base_name->length);
pos+= base_name->length;
// set_name() will allocate the name
item->set_name(buff,(uint) (pos-buff)+var->name_length, system_charset_info);
item->set_name(buff,(uint) (pos-buff), system_charset_info);
return item;
}
Item *get_system_var(enum_var_type var_type, const char *var_name, uint length,
const char *item_name)
Item *get_system_var(THD *thd, enum_var_type var_type, const char *var_name,
uint length, const char *item_name)
{
THD *thd=current_thd;
Item *item;
sys_var *var;
LEX_STRING null_lex_string;
null_lex_string.str= 0;
var= find_sys_var(var_name, length);
DBUG_ASSERT(var != 0);
if (!(item=var->item(thd, var_type)))
if (!(item=var->item(thd, var_type, &null_lex_string)))
return 0; // Impossible
thd->lex.uncacheable();
item->set_name(item_name, 0, system_charset_info); // Will use original name
......
......@@ -770,6 +770,7 @@ extern rw_lock_t LOCK_grant;
extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager;
extern pthread_attr_t connection_attrib;
extern I_List<THD> threads;
extern I_List<NAMED_LIST> key_caches;
extern MY_BITMAP temp_pool;
extern DATE_FORMAT dayord;
extern String empty_string;
......@@ -903,9 +904,10 @@ extern void sql_cache_free();
extern int sql_cache_hit(THD *thd, char *inBuf, uint length);
/* item.cc */
Item *get_system_var(enum_var_type var_type, LEX_STRING name);
Item *get_system_var(enum_var_type var_type, const char *var_name, uint length,
const char *item_name);
Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
LEX_STRING component);
Item *get_system_var(THD *thd, enum_var_type var_type, const char *var_name,
uint length, const char *item_name);
/* log.cc */
bool flush_error_log(void);
......
......@@ -312,11 +312,12 @@ const char *sql_mode_str="OFF";
FILE *bootstrap_file;
I_List <i_string_pair> replicate_rewrite_db;
I_List<i_string_pair> replicate_rewrite_db;
I_List<i_string> replicate_do_db, replicate_ignore_db;
// allow the user to tell us which db to replicate and which to ignore
I_List<i_string> binlog_do_db, binlog_ignore_db;
I_List<THD> threads,thread_cache;
I_List<NAMED_LIST> key_caches;
struct system_variables global_system_variables;
struct system_variables max_system_variables;
......@@ -875,6 +876,7 @@ void clean_up(bool print_message)
#endif
(void) ha_panic(HA_PANIC_CLOSE); /* close all tables and logs */
end_key_cache();
delete_elements(&key_caches, free_key_cache);
end_thr_alarm(1); /* Free allocated memory */
#ifdef USE_RAID
end_raid();
......@@ -4103,7 +4105,7 @@ replicating a LOAD DATA INFILE command.",
REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD,
IO_SIZE, 0},
{"key_buffer_size", OPT_KEY_BUFFER_SIZE,
"The size of the buffer used for index blocks. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.",
"The size of the buffer used for index blocks for MyISAM tables. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.",
(gptr*) &keybuff_size, (gptr*) &keybuff_size, 0,
(enum get_opt_var_type) (GET_ULL | GET_ASK_ADDR),
REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD,
......@@ -4679,6 +4681,9 @@ static void mysql_init_variables(void)
my_bind_addr = htonl(INADDR_ANY);
threads.empty();
thread_cache.empty();
key_caches.empty();
if (!get_or_create_key_cache("default", 7))
exit(1);
/* Initialize structures that is used when processing options */
replicate_rewrite_db.empty();
......@@ -5309,16 +5314,30 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
}
return 0;
}
/* Initiates DEBUG - but no debugging here ! */
extern "C" gptr *
mysql_getopt_value(char *keyname, uint key_length,
mysql_getopt_value(const char *keyname, uint key_length,
const struct my_option *option)
{
if (!key_length)
{
keyname= "default";
key_length= 7;
}
switch (option->id) {
case OPT_KEY_BUFFER_SIZE:
{
KEY_CACHE *key_cache;
if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
exit(1);
return (gptr*) &key_cache->size;
}
}
return option->value;
}
static void get_options(int argc,char **argv)
{
int ho_error;
......@@ -5366,6 +5385,8 @@ static void get_options(int argc,char **argv)
table_alias_charset= (lower_case_table_names ?
files_charset_info :
&my_charset_bin);
/* QQ To be deleted when we have key cache variables in a struct */
keybuff_size= (((KEY_CACHE *) find_named(&key_caches, "default", 7))->size);
}
......@@ -5580,6 +5601,6 @@ template class I_List<THD>;
template class I_List_iterator<THD>;
template class I_List<i_string>;
template class I_List<i_string_pair>;
template class I_List<NAMED_LIST>;
FIX_GCC_LINKING_PROBLEM
#endif
This diff is collapsed.
......@@ -47,12 +47,18 @@ class sys_var
struct my_option *option_limits; /* Updated by by set_var_init() */
uint name_length; /* Updated by by set_var_init() */
const char *name;
LEX_STRING base_name; /* for structs */
sys_after_update_func after_update;
sys_var(const char *name_arg) :name(name_arg),after_update(0)
{}
{
base_name.length=0;
}
sys_var(const char *name_arg,sys_after_update_func func)
:name(name_arg),after_update(func)
{}
{
base_name.length=0;
}
virtual ~sys_var() {}
virtual bool check(THD *thd, set_var *var) { return 0; }
bool check_enum(THD *thd, set_var *var, TYPELIB *enum_names);
......@@ -60,14 +66,16 @@ class sys_var
virtual bool update(THD *thd, set_var *var)=0;
virtual void set_default(THD *thd, enum_var_type type) {}
virtual SHOW_TYPE type() { return SHOW_UNDEF; }
virtual byte *value_ptr(THD *thd, enum_var_type type) { return 0; }
virtual byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
{ return 0; }
virtual bool check_type(enum_var_type type)
{ return type != OPT_GLOBAL; } /* Error if not GLOBAL */
virtual bool check_update_type(Item_result type)
{ return type != INT_RESULT; } /* Assume INT */
virtual bool check_default(enum_var_type type)
{ return option_limits == 0; }
Item *item(THD *thd, enum_var_type type);
Item *item(THD *thd, enum_var_type type, LEX_STRING *base);
virtual bool is_struct() { return 0; }
};
......@@ -83,7 +91,8 @@ class sys_var_long_ptr :public sys_var
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
SHOW_TYPE type() { return SHOW_LONG; }
byte *value_ptr(THD *thd, enum_var_type type) { return (byte*) value; }
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
{ return (byte*) value; }
};
......@@ -99,7 +108,8 @@ class sys_var_ulonglong_ptr :public sys_var
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
SHOW_TYPE type() { return SHOW_LONGLONG; }
byte *value_ptr(THD *thd, enum_var_type type) { return (byte*) value; }
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
{ return (byte*) value; }
};
......@@ -117,7 +127,8 @@ class sys_var_bool_ptr :public sys_var
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
SHOW_TYPE type() { return SHOW_MY_BOOL; }
byte *value_ptr(THD *thd, enum_var_type type) { return (byte*) value; }
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
{ return (byte*) value; }
bool check_update_type(Item_result type) { return 0; }
};
......@@ -149,7 +160,8 @@ class sys_var_str :public sys_var
(*set_default_func)(thd, type);
}
SHOW_TYPE type() { return SHOW_CHAR; }
byte *value_ptr(THD *thd, enum_var_type type) { return (byte*) value; }
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
{ return (byte*) value; }
bool check_update_type(Item_result type)
{
return type != STRING_RESULT; /* Only accept strings */
......@@ -173,7 +185,7 @@ class sys_var_enum :public sys_var
}
bool update(THD *thd, set_var *var);
SHOW_TYPE type() { return SHOW_CHAR; }
byte *value_ptr(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
bool check_update_type(Item_result type) { return 0; }
};
......@@ -209,7 +221,7 @@ class sys_var_thd_ulong :public sys_var_thd
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
SHOW_TYPE type() { return SHOW_LONG; }
byte *value_ptr(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
};
class sys_var_pseudo_thread_id :public sys_var_thd_ulong
......@@ -236,7 +248,7 @@ class sys_var_thd_ha_rows :public sys_var_thd
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
SHOW_TYPE type() { return SHOW_HA_ROWS; }
byte *value_ptr(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
};
......@@ -256,7 +268,7 @@ class sys_var_thd_ulonglong :public sys_var_thd
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
SHOW_TYPE type() { return SHOW_LONGLONG; }
byte *value_ptr(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
bool check_default(enum_var_type type)
{
return type == OPT_GLOBAL && !option_limits;
......@@ -282,7 +294,7 @@ class sys_var_thd_bool :public sys_var_thd
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
SHOW_TYPE type() { return SHOW_MY_BOOL; }
byte *value_ptr(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
bool check(THD *thd, set_var *var)
{
return check_enum(thd, var, &bool_typelib);
......@@ -313,7 +325,7 @@ class sys_var_thd_enum :public sys_var_thd
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
SHOW_TYPE type() { return SHOW_CHAR; }
byte *value_ptr(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
bool check_update_type(Item_result type) { return 0; }
};
......@@ -332,7 +344,7 @@ class sys_var_thd_sql_mode :public sys_var_thd_enum
return check_set(thd, var, enum_names);
}
void set_default(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
};
......@@ -355,7 +367,7 @@ class sys_var_thd_bit :public sys_var_thd
bool check_update_type(Item_result type) { return 0; }
bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
SHOW_TYPE type() { return SHOW_MY_BOOL; }
byte *value_ptr(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
};
......@@ -370,7 +382,7 @@ class sys_var_timestamp :public sys_var
bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
bool check_default(enum_var_type type) { return 0; }
SHOW_TYPE type() { return SHOW_LONG; }
byte *value_ptr(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
};
......@@ -381,7 +393,7 @@ class sys_var_last_insert_id :public sys_var
bool update(THD *thd, set_var *var);
bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
SHOW_TYPE type() { return SHOW_LONGLONG; }
byte *value_ptr(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
};
......@@ -392,7 +404,7 @@ class sys_var_insert_id :public sys_var
bool update(THD *thd, set_var *var);
bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
SHOW_TYPE type() { return SHOW_LONGLONG; }
byte *value_ptr(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
};
......@@ -456,7 +468,7 @@ SHOW_TYPE type() { return SHOW_CHAR; }
}
bool check_default(enum_var_type type) { return 0; }
bool update(THD *thd, set_var *var);
byte *value_ptr(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
virtual void set_default(THD *thd, enum_var_type type)= 0;
virtual CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type)= 0;
};
......@@ -513,9 +525,24 @@ class sys_var_collation_connection :public sys_var_collation
sys_var_collation_connection(const char *name_arg) :sys_var_collation(name_arg) {}
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
};
class sys_var_key_buffer_size :public sys_var
{
public:
sys_var_key_buffer_size(const char *name_arg)
:sys_var(name_arg)
{}
bool update(THD *thd, set_var *var);
SHOW_TYPE type() { return SHOW_LONGLONG; }
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
bool check_default(enum_var_type type) { return 1; }
bool is_struct() { return 1; }
};
/* Variable that you can only read from */
class sys_var_readonly: public sys_var
......@@ -534,7 +561,7 @@ class sys_var_readonly: public sys_var
bool check_default(enum_var_type type) { return 1; }
bool check_type(enum_var_type type) { return type != var_type; }
bool check_update_type(Item_result type) { return 1; }
byte *value_ptr(THD *thd, enum_var_type type)
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
{
return (*value_ptr_func)(thd);
}
......@@ -639,6 +666,33 @@ class set_var_collation_client: public set_var_base
};
/* Named lists (used for keycaches) */
class NAMED_LIST :public ilink
{
const char *name;
uint name_length;
public:
gptr data;
NAMED_LIST(I_List<NAMED_LIST> *links, const char *name_arg,
uint name_length_arg, gptr data_arg):
name_length(name_length_arg), data(data_arg)
{
name=my_strdup(name_arg,MYF(MY_WME));
links->push_back(this);
}
inline bool cmp(const char *name_cmp, uint length)
{
return length == name_length && !memcmp(name, name_cmp, length);
}
~NAMED_LIST()
{
my_free((char*) name, MYF(0));
}
};
/*
Prototypes for helper functions
*/
......@@ -649,6 +703,11 @@ sys_var *find_sys_var(const char *str, uint length=0);
int sql_set_variables(THD *thd, List<set_var_base> *var_list);
void fix_delay_key_write(THD *thd, enum_var_type type);
ulong fix_sql_mode(ulong sql_mode);
extern sys_var_str sys_charset_system;
CHARSET_INFO *get_old_charset_by_name(const char *old_name);
gptr find_named(I_List<NAMED_LIST> *list, const char *name, uint length);
void delete_elements(I_List<NAMED_LIST> *list, void (*free_element)(gptr));
/* key_cache functions */
KEY_CACHE *get_or_create_key_cache(const char *name, uint length);
void free_key_cache(gptr key_cache);
......@@ -275,3 +275,4 @@ v/*
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -269,3 +269,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -277,3 +277,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -271,3 +271,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -271,3 +271,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -266,3 +266,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -275,3 +275,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -266,3 +266,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -268,3 +268,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -266,3 +266,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -268,3 +268,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -266,3 +266,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -268,3 +268,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -268,3 +268,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -270,3 +270,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -266,3 +266,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -270,3 +270,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -268,3 +268,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -262,3 +262,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -274,3 +274,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -267,3 +267,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -266,3 +266,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -271,3 +271,4 @@
"Can't revoke all privileges, grant for one or more of the requested users"
"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'",
"Illegal mix of collations for operation '%s'",
"Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)",
......@@ -557,10 +557,12 @@ int yylex(void *arg, void *yythd)
return(IDENT);
case MY_LEX_IDENT_SEP: // Found ident and now '.'
lex->next_state=MY_LEX_IDENT_START;// Next is an ident (not a keyword)
yylval->lex_str.str=(char*) lex->ptr;
yylval->lex_str.length=1;
c=yyGet(); // should be '.'
lex->next_state= MY_LEX_IDENT_START;// Next is an ident (not a keyword)
if (!ident_map[yyPeek()]) // Probably ` or "
lex->next_state= MY_LEX_START;
return((int) c);
case MY_LEX_NUMBER_IDENT: // number or ident which num-start
......@@ -601,7 +603,7 @@ int yylex(void *arg, void *yythd)
yyUnget();
}
// fall through
case MY_LEX_IDENT_START: // Incomplete ident
case MY_LEX_IDENT_START: // We come here after '.'
#if defined(USE_MB) && defined(USE_MB_IDENT)
if (use_mb(cs))
{
......@@ -689,6 +691,7 @@ int yylex(void *arg, void *yythd)
}
if (c == delim)
yySkip(); // Skip end `
lex->next_state= MY_LEX_START;
return(IDENT);
}
case MY_LEX_SIGNED_NUMBER: // Incomplete signed number
......@@ -707,9 +710,9 @@ int yylex(void *arg, void *yythd)
if (c != '.')
{
if (c == '-' && my_isspace(cs,yyPeek()))
state=MY_LEX_COMMENT;
state= MY_LEX_COMMENT;
else
state = MY_LEX_CHAR; // Return sign as single char
state= MY_LEX_CHAR; // Return sign as single char
break;
}
yyUnget(); // Fix for next loop
......@@ -868,7 +871,7 @@ int yylex(void *arg, void *yythd)
else
state=MY_LEX_CHAR; // Return '*'
break;
case MY_LEX_SET_VAR: // Check if ':='
case MY_LEX_SET_VAR: // Check if ':='
if (yyPeek() != '=')
{
state=MY_LEX_CHAR; // Return ':'
......@@ -904,8 +907,8 @@ int yylex(void *arg, void *yythd)
state = MY_LEX_REAL; // Real
else
{
state = MY_LEX_CHAR; // return '.'
lex->next_state=MY_LEX_IDENT_START;// Next is an ident (not a keyword)
state= MY_LEX_IDENT_SEP; // return '.'
yyUnget(); // Put back '.'
}
break;
case MY_LEX_USER_END: // end '@' of user@hostname
......@@ -933,8 +936,11 @@ int yylex(void *arg, void *yythd)
case MY_LEX_SYSTEM_VAR:
yylval->lex_str.str=(char*) lex->ptr;
yylval->lex_str.length=1;
lex->next_state=MY_LEX_IDENT_OR_KEYWORD;
yySkip(); // Skip '@'
lex->next_state= (state_map[yyPeek()] ==
MY_LEX_USER_VARIABLE_DELIMITER ?
MY_LEX_OPERATOR_OR_IDENT :
MY_LEX_IDENT_OR_KEYWORD);
return((int) '@');
case MY_LEX_IDENT_OR_KEYWORD:
/*
......@@ -942,7 +948,6 @@ int yylex(void *arg, void *yythd)
We should now be able to handle:
[(global | local | session) .]variable_name
*/
while (ident_map[c=yyGet()]) ;
if (c == '.')
lex->next_state=MY_LEX_IDENT_SEP;
......
......@@ -3570,15 +3570,20 @@ mysql_new_select(LEX *lex, bool move_down)
void create_select_for_variable(const char *var_name)
{
THD *thd;
LEX *lex;
LEX_STRING tmp;
LEX_STRING tmp, null_lex_string;
DBUG_ENTER("create_select_for_variable");
lex= current_lex;
thd= current_thd;
lex= &thd->lex;
mysql_init_select(lex);
lex->sql_command= SQLCOM_SELECT;
tmp.str= (char*) var_name;
tmp.length=strlen(var_name);
add_item_to_list(lex->thd, get_system_var(OPT_SESSION, tmp));
bzero((char*) &null_lex_string.str, sizeof(null_lex_string));
add_item_to_list(thd, get_system_var(thd, OPT_SESSION, tmp,
null_lex_string));
DBUG_VOID_RETURN;
}
......
......@@ -1527,12 +1527,14 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
char buff[1024];
List<Item> field_list;
Protocol *protocol= thd->protocol;
LEX_STRING null_lex_str;
DBUG_ENTER("mysqld_show");
field_list.push_back(new Item_empty_string("Variable_name",30));
field_list.push_back(new Item_empty_string("Value",256));
if (protocol->send_fields(&field_list,1))
DBUG_RETURN(1); /* purecov: inspected */
null_lex_str.str= 0; // For sys_var->value_ptr()
/* pthread_mutex_lock(&THR_LOCK_keycache); */
pthread_mutex_lock(&LOCK_status);
......@@ -1551,7 +1553,8 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
if (show_type == SHOW_SYS)
{
show_type= ((sys_var*) value)->type();
value= (char*) ((sys_var*) value)->value_ptr(thd, value_type);
value= (char*) ((sys_var*) value)->value_ptr(thd, value_type,
&null_lex_str);
}
pos= end= buff;
......
......@@ -561,7 +561,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
IDENT TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME
ULONGLONG_NUM field_ident select_alias ident ident_or_text
UNDERSCORE_CHARSET IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
NCHAR_STRING
NCHAR_STRING opt_component
%type <lex_str_ptr>
opt_table_alias
......@@ -1532,6 +1532,10 @@ opt_ident:
/* empty */ { $$=(char*) 0; } /* Defaultlength */
| field_ident { $$=$1.str; };
opt_component:
/* empty */ { $$.str= 0; $$.length= 0; }
| '.' ident { $$=$2; };
string_list:
text_string { Lex->interval_list.push_back($1); }
| string_list ',' text_string { Lex->interval_list.push_back($3); };
......@@ -2276,9 +2280,9 @@ simple_expr:
$$= new Item_func_get_user_var($2);
Lex->uncacheable();
}
| '@' '@' opt_var_ident_type ident_or_text
| '@' '@' opt_var_ident_type ident_or_text opt_component
{
if (!($$= get_system_var((enum_var_type) $3, $4)))
if (!($$= get_system_var(YYTHD, (enum_var_type) $3, $4, $5)))
YYABORT;
}
| sum_expr
......@@ -2440,7 +2444,7 @@ simple_expr:
}
| LAST_INSERT_ID '(' ')'
{
$$= get_system_var(OPT_SESSION, "last_insert_id", 14,
$$= get_system_var(YYTHD, OPT_SESSION, "last_insert_id", 14,
"last_insert_id()");
Lex->safe_to_cache_query= 0;
}
......@@ -4590,6 +4594,27 @@ internal_variable_name:
YYABORT;
$$=tmp;
}
| ident '.' ident
{
sys_var *tmp=find_sys_var($3.str, $3.length);
if (!tmp)
YYABORT;
if (!tmp->is_struct())
net_printf(YYTHD, ER_VARIABLE_IS_NOT_STRUCT, $3.str);
tmp->base_name= $1;
$$=tmp;
}
| DEFAULT '.' ident
{
sys_var *tmp=find_sys_var($3.str, $3.length);
if (!tmp)
YYABORT;
if (!tmp->is_struct())
net_printf(YYTHD, ER_VARIABLE_IS_NOT_STRUCT, $3.str);
tmp->base_name.str= (char*) "default";
tmp->base_name.length= 7;
$$=tmp;
}
;
isolation_types:
......
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