diff options
author | monty@mashka.mysql.fi <> | 2003-07-08 23:54:48 +0300 |
---|---|---|
committer | monty@mashka.mysql.fi <> | 2003-07-08 23:54:48 +0300 |
commit | 39e7db9f51fb9f78d7c3846ad11afd1f13778593 (patch) | |
tree | 6605f287527ecbfa819a64516db88bfd63ff07ea /sql | |
parent | a4ad9b4ae6a5d7b5529f1ffff94d092110cb6a32 (diff) | |
parent | 8b54bff34cbdff9f3f27224ccd7a4c36d128ea43 (diff) | |
download | mariadb-git-39e7db9f51fb9f78d7c3846ad11afd1f13778593.tar.gz |
Merge bk-internal.mysql.com:/home/bk/mysql-4.1
into mashka.mysql.fi:/home/my/mysql-4.1
Diffstat (limited to 'sql')
33 files changed, 442 insertions, 95 deletions
diff --git a/sql/Makefile.am b/sql/Makefile.am index fd02cc906d7..5781b6181d2 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -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 $< diff --git a/sql/item_func.cc b/sql/item_func.cc index ad2bebf9efb..7264a3b5225 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -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 diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index edbc30bfe87..65451ca40b5 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -773,6 +773,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; @@ -907,9 +908,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); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 0a3985c3ee9..709ba036f7e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -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 diff --git a/sql/set_var.cc b/sql/set_var.cc index a281fac530a..cb6c875d513 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -86,9 +86,9 @@ static void fix_net_retry_count(THD *thd, enum_var_type type); static void fix_max_join_size(THD *thd, enum_var_type type); static void fix_query_cache_size(THD *thd, enum_var_type type); static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type); -static void fix_key_buffer_size(THD *thd, enum_var_type type); static void fix_myisam_max_extra_sort_file_size(THD *thd, enum_var_type type); static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type); +static KEY_CACHE *create_key_cache(const char *name, uint length); void fix_sql_mode_var(THD *thd, enum_var_type type); static byte *get_error_count(THD *thd); static byte *get_warning_count(THD *thd); @@ -136,9 +136,7 @@ sys_var_thd_ulong sys_interactive_timeout("interactive_timeout", &SV::net_interactive_timeout); sys_var_thd_ulong sys_join_buffer_size("join_buffer_size", &SV::join_buff_size); -sys_var_ulonglong_ptr sys_key_buffer_size("key_buffer_size", - &keybuff_size, - fix_key_buffer_size); +sys_var_key_buffer_size sys_key_buffer_size("key_buffer_size"); sys_var_bool_ptr sys_local_infile("local_infile", &opt_local_infile); sys_var_thd_bool sys_log_warnings("log_warnings", &SV::log_warnings); @@ -793,12 +791,6 @@ static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type) #endif -static void fix_key_buffer_size(THD *thd, enum_var_type type) -{ - ha_resize_key_cache(); -} - - void fix_delay_key_write(THD *thd, enum_var_type type) { switch ((enum_delay_key_write) delay_key_write_options) { @@ -870,7 +862,7 @@ bool sys_var_enum::update(THD *thd, set_var *var) } -byte *sys_var_enum::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_enum::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base) { return (byte*) enum_names->type_names[*value]; } @@ -906,7 +898,8 @@ void sys_var_thd_ulong::set_default(THD *thd, enum_var_type type) } -byte *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { if (type == OPT_GLOBAL) return (byte*) &(global_system_variables.*offset); @@ -951,7 +944,8 @@ void sys_var_thd_ha_rows::set_default(THD *thd, enum_var_type type) } -byte *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { if (type == OPT_GLOBAL) return (byte*) &(global_system_variables.*offset); @@ -994,7 +988,8 @@ void sys_var_thd_ulonglong::set_default(THD *thd, enum_var_type type) } -byte *sys_var_thd_ulonglong::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_thd_ulonglong::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { if (type == OPT_GLOBAL) return (byte*) &(global_system_variables.*offset); @@ -1021,7 +1016,8 @@ void sys_var_thd_bool::set_default(THD *thd, enum_var_type type) } -byte *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { if (type == OPT_GLOBAL) return (byte*) &(global_system_variables.*offset); @@ -1115,7 +1111,7 @@ err: to create an item that gets the current value at fix_fields() stage. */ -Item *sys_var::item(THD *thd, enum_var_type var_type) +Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) { if (check_type(var_type)) { @@ -1131,16 +1127,16 @@ Item *sys_var::item(THD *thd, enum_var_type var_type) } switch (type()) { case SHOW_LONG: - return new Item_uint((int32) *(ulong*) value_ptr(thd, var_type)); + return new Item_uint((int32) *(ulong*) value_ptr(thd, var_type, base)); case SHOW_LONGLONG: - return new Item_int(*(longlong*) value_ptr(thd, var_type)); + return new Item_int(*(longlong*) value_ptr(thd, var_type, base)); case SHOW_HA_ROWS: - return new Item_int((longlong) *(ha_rows*) value_ptr(thd, var_type)); + return new Item_int((longlong) *(ha_rows*) value_ptr(thd, var_type, base)); case SHOW_MY_BOOL: - return new Item_int((int32) *(my_bool*) value_ptr(thd, var_type),1); + return new Item_int((int32) *(my_bool*) value_ptr(thd, var_type, base),1); case SHOW_CHAR: { - char *str= (char*) value_ptr(thd, var_type); + char *str= (char*) value_ptr(thd, var_type, base); return new Item_string(str, strlen(str), system_charset_info); } default: @@ -1169,7 +1165,8 @@ void sys_var_thd_enum::set_default(THD *thd, enum_var_type type) } -byte *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { ulong tmp= ((type == OPT_GLOBAL) ? global_system_variables.*offset : @@ -1186,7 +1183,8 @@ bool sys_var_thd_bit::update(THD *thd, set_var *var) } -byte *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { /* If reverse is 0 (default) return 1 if bit is set. @@ -1249,6 +1247,7 @@ bool sys_var_collation::check(THD *thd, set_var *var) return 0; } + bool sys_var_character_set::check(THD *thd, set_var *var) { CHARSET_INFO *tmp; @@ -1274,20 +1273,24 @@ bool sys_var_character_set::check(THD *thd, set_var *var) return 0; } + bool sys_var_character_set::update(THD *thd, set_var *var) { ci_ptr(thd,var->type)[0]= var->save_result.charset; return 0; } -byte *sys_var_character_set::value_ptr(THD *thd, enum_var_type type) + +byte *sys_var_character_set::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { CHARSET_INFO *cs= ci_ptr(thd,type)[0]; return cs ? (byte*) cs->csname : (byte*) "NULL"; } -CHARSET_INFO ** sys_var_character_set_connection::ci_ptr(THD *thd, enum_var_type type) +CHARSET_INFO ** sys_var_character_set_connection::ci_ptr(THD *thd, + enum_var_type type) { if (type == OPT_GLOBAL) return &global_system_variables.collation_connection; @@ -1295,7 +1298,9 @@ CHARSET_INFO ** sys_var_character_set_connection::ci_ptr(THD *thd, enum_var_type return &thd->variables.collation_connection; } -void sys_var_character_set_connection::set_default(THD *thd, enum_var_type type) + +void sys_var_character_set_connection::set_default(THD *thd, + enum_var_type type) { if (type == OPT_GLOBAL) global_system_variables.collation_connection= default_charset_info; @@ -1304,7 +1309,8 @@ void sys_var_character_set_connection::set_default(THD *thd, enum_var_type type) } -CHARSET_INFO ** sys_var_character_set_client::ci_ptr(THD *thd, enum_var_type type) +CHARSET_INFO ** sys_var_character_set_client::ci_ptr(THD *thd, + enum_var_type type) { if (type == OPT_GLOBAL) return &global_system_variables.character_set_client; @@ -1312,6 +1318,7 @@ CHARSET_INFO ** sys_var_character_set_client::ci_ptr(THD *thd, enum_var_type typ return &thd->variables.character_set_client; } + void sys_var_character_set_client::set_default(THD *thd, enum_var_type type) { if (type == OPT_GLOBAL) @@ -1320,6 +1327,7 @@ void sys_var_character_set_client::set_default(THD *thd, enum_var_type type) thd->variables.character_set_client= global_system_variables.character_set_client; } + CHARSET_INFO ** sys_var_character_set_results::ci_ptr(THD *thd, enum_var_type type) { if (type == OPT_GLOBAL) @@ -1328,6 +1336,7 @@ CHARSET_INFO ** sys_var_character_set_results::ci_ptr(THD *thd, enum_var_type ty return &thd->variables.character_set_results; } + void sys_var_character_set_results::set_default(THD *thd, enum_var_type type) { if (type == OPT_GLOBAL) @@ -1336,6 +1345,7 @@ void sys_var_character_set_results::set_default(THD *thd, enum_var_type type) thd->variables.character_set_results= global_system_variables.character_set_results; } + CHARSET_INFO ** sys_var_character_set_server::ci_ptr(THD *thd, enum_var_type type) { if (type == OPT_GLOBAL) @@ -1344,6 +1354,7 @@ CHARSET_INFO ** sys_var_character_set_server::ci_ptr(THD *thd, enum_var_type typ return &thd->variables.character_set_server; } + void sys_var_character_set_server::set_default(THD *thd, enum_var_type type) { if (type == OPT_GLOBAL) @@ -1352,7 +1363,9 @@ void sys_var_character_set_server::set_default(THD *thd, enum_var_type type) thd->variables.character_set_server= global_system_variables.character_set_server; } -CHARSET_INFO ** sys_var_character_set_database::ci_ptr(THD *thd, enum_var_type type) + +CHARSET_INFO ** sys_var_character_set_database::ci_ptr(THD *thd, + enum_var_type type) { if (type == OPT_GLOBAL) return &global_system_variables.character_set_database; @@ -1360,6 +1373,7 @@ CHARSET_INFO ** sys_var_character_set_database::ci_ptr(THD *thd, enum_var_type t return &thd->variables.character_set_database; } + void sys_var_character_set_database::set_default(THD *thd, enum_var_type type) { if (type == OPT_GLOBAL) @@ -1368,6 +1382,7 @@ void sys_var_character_set_database::set_default(THD *thd, enum_var_type type) thd->variables.character_set_database= thd->db_charset; } + bool sys_var_collation_connection::update(THD *thd, set_var *var) { if (var->type == OPT_GLOBAL) @@ -1377,7 +1392,9 @@ bool sys_var_collation_connection::update(THD *thd, set_var *var) return 0; } -byte *sys_var_collation_connection::value_ptr(THD *thd, enum_var_type type) + +byte *sys_var_collation_connection::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { CHARSET_INFO *cs= ((type == OPT_GLOBAL) ? global_system_variables.collation_connection : @@ -1385,6 +1402,7 @@ byte *sys_var_collation_connection::value_ptr(THD *thd, enum_var_type type) return cs ? (byte*) cs->name : (byte*) "NULL"; } + void sys_var_collation_connection::set_default(THD *thd, enum_var_type type) { if (type == OPT_GLOBAL) @@ -1394,6 +1412,71 @@ void sys_var_collation_connection::set_default(THD *thd, enum_var_type type) } +bool sys_var_key_buffer_size::update(THD *thd, set_var *var) +{ + ulonglong tmp= var->value->val_int(); + if (!base_name.length) + { + base_name.str= (char*) "default"; + base_name.length= 7; + } + KEY_CACHE *key_cache= (KEY_CACHE*) find_named(&key_caches, base_name.str, + base_name.length); + if (!key_cache) + { + if (!tmp) // Tried to delete cache + return 0; // Ok, nothing to do + if (!(key_cache= create_key_cache(base_name.str, + base_name.length))) + return 1; + } + if (!tmp) + { + /* Delete not default key caches */ + if (base_name.length != 7 || memcpy(base_name.str, "default", 7)) + { + /* + QQ: Here we should move tables using this key cache to default + key cache + */ + delete key_cache; + return 0; + } + } + + key_cache->size= (ulonglong) getopt_ull_limit_value(tmp, option_limits); + + /* QQ: Needs to be updated when we have multiple key caches */ + keybuff_size= key_cache->size; + ha_resize_key_cache(); + return 0; +} + +static ulonglong zero=0; + +byte *sys_var_key_buffer_size::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) +{ + const char *name; + uint length; + + if (!base->str) + { + name= "default"; + length= 7; + } + else + { + name= base->str; + length= base->length; + } + KEY_CACHE *key_cache= (KEY_CACHE*) find_named(&key_caches, name, length); + if (!key_cache) + return (byte*) &zero; + return (byte*) &key_cache->size; +} + + /***************************************************************************** Functions to handle SET NAMES and SET CHARACTER SET @@ -1429,7 +1512,8 @@ void sys_var_timestamp::set_default(THD *thd, enum_var_type type) } -byte *sys_var_timestamp::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_timestamp::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { thd->sys_var_tmp.long_value= (long) thd->start_time; return (byte*) &thd->sys_var_tmp.long_value; @@ -1443,7 +1527,8 @@ bool sys_var_last_insert_id::update(THD *thd, set_var *var) } -byte *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { thd->sys_var_tmp.long_value= (long) thd->insert_id(); return (byte*) &thd->last_insert_id; @@ -1457,7 +1542,8 @@ bool sys_var_insert_id::update(THD *thd, set_var *var) } -byte *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { return (byte*) &thd->current_insert_id; } @@ -1848,7 +1934,8 @@ int set_var_password::update(THD *thd) Functions to handle sql_mode ****************************************************************************/ -byte *sys_var_thd_sql_mode::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_thd_sql_mode::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { ulong val; char buff[256]; @@ -1945,6 +2032,68 @@ ulong fix_sql_mode(ulong sql_mode) } +/**************************************************************************** + Named list handling +****************************************************************************/ + +gptr find_named(I_List<NAMED_LIST> *list, const char *name, uint length) +{ + I_List_iterator<NAMED_LIST> it(*list); + NAMED_LIST *element; + while ((element= it++)) + { + if (element->cmp(name, length)) + return element->data; + } + return 0; +} + + +void delete_elements(I_List<NAMED_LIST> *list, void (*free_element)(gptr)) +{ + NAMED_LIST *element; + while ((element= list->get())) + { + (*free_element)(element->data); + delete element; + } +} + + +/* Key cache functions */ + +static KEY_CACHE *create_key_cache(const char *name, uint length) +{ + KEY_CACHE *key_cache; + DBUG_PRINT("info",("Creating key cache: %s", name)); + if ((key_cache= (KEY_CACHE*) my_malloc(sizeof(KEY_CACHE), + MYF(MY_ZEROFILL | MY_WME)))) + { + if (!new NAMED_LIST(&key_caches, name, length, (gptr) key_cache)) + { + my_free((char*) key_cache, MYF(0)); + key_cache= 0; + } + } + return key_cache; +} + + +KEY_CACHE *get_or_create_key_cache(const char *name, uint length) +{ + KEY_CACHE *key_cache= (KEY_CACHE*) find_named(&key_caches, name, + length); + if (!key_cache) + key_cache= create_key_cache(name, length); + return key_cache; +} + + +void free_key_cache(gptr key_cache) +{ + my_free(key_cache, MYF(0)); +} + /**************************************************************************** Used templates @@ -1953,4 +2102,5 @@ ulong fix_sql_mode(ulong sql_mode) #ifdef __GNUC__ template class List<set_var_base>; template class List_iterator_fast<set_var_base>; +template class I_List_iterator<NAMED_LIST>; #endif diff --git a/sql/set_var.h b/sql/set_var.h index 5a0fbd21809..978aba3384a 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -47,12 +47,18 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: (*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 @@ public: } 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: }; +/* 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); diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index f179b311c83..30516e8dad1 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -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)", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 58466ed32f7..289f70c79ed 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -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)", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 6296c39d232..8cf926554a4 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -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)", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 5a9c44ef07e..6f0de413a47 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -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)", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index de22d6fd111..f4107e91d5b 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -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)", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index e9a80c44f7f..5d82eebefda 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -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)", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 00f0699445f..4512cd1e0cb 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -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)", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 347370f1ac8..873f8385462 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -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)", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 313275b3cb6..93ab550b60f 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -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)", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 677d20a535b..cc21f7cf42a 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -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)", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 417a03978fb..b8bc6e1d761 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -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)", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 22395d0fb6a..9bbcaa16076 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -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)", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 6d9ac18be34..f562553e40a 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -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)", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index ba7c108f9ae..dcb7be9a053 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -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)", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 04e60f5aa95..9cd63dfc009 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -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)", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 64d83c20aab..14a1e6763b4 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -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)", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index e62c857553b..c5be6e5df8d 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -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)", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index ec41a6acb34..e193eac6793 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -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)", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 62e5519475f..e413097a997 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -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)", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 7730a4220ba..a3e34b8b41a 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -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)", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 8f923312969..c1b3f19da4f 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -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)", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index ed60fc62387..b1153c83504 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -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)", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 5a614714de2..2fc14372f54 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -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)", diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 2eeb57f34a7..425890ab446 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -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; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 00917e296ca..9e670a97e92 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3575,15 +3575,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; } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index fae01936357..e8cb59e387e 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -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; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4aa5b70407e..3098bd18b2d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -569,7 +569,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 @@ -1540,6 +1540,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); }; @@ -2284,9 +2288,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 @@ -2456,7 +2460,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; } @@ -4626,6 +4630,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: |