diff options
Diffstat (limited to 'sql/set_var.h')
-rw-r--r-- | sql/set_var.h | 274 |
1 files changed, 243 insertions, 31 deletions
diff --git a/sql/set_var.h b/sql/set_var.h index e22c55276a7..f06b5ed22d3 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -28,7 +28,7 @@ class sys_var; class set_var; typedef struct system_variables SV; -extern TYPELIB bool_typelib, delay_key_write_typelib; +extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib; enum enum_var_type { @@ -39,6 +39,7 @@ typedef bool (*sys_check_func)(THD *, set_var *); typedef bool (*sys_update_func)(THD *, set_var *); typedef void (*sys_after_update_func)(THD *,enum_var_type); typedef void (*sys_set_default_func)(THD *, enum_var_type); +typedef byte *(*sys_value_ptr_func)(THD *thd); class sys_var { @@ -46,6 +47,7 @@ public: struct my_option *option_limits; /* Updated by by set_var_init() */ uint name_length; /* Updated by by set_var_init() */ const char *name; + sys_after_update_func after_update; sys_var(const char *name_arg) :name(name_arg),after_update(0) {} @@ -55,17 +57,20 @@ public: virtual ~sys_var() {} virtual bool check(THD *thd, set_var *var) { return 0; } bool check_enum(THD *thd, set_var *var, TYPELIB *enum_names); + bool check_set(THD *thd, set_var *var, TYPELIB *enum_names); 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; } }; @@ -81,7 +86,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; } }; @@ -97,7 +103,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; } }; @@ -115,7 +122,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; } }; @@ -147,7 +155,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 */ @@ -171,7 +180,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; } }; @@ -207,7 +216,16 @@ 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 +{ +public: + sys_var_pseudo_thread_id(const char *name_arg, ulong SV::*offset_arg) + :sys_var_thd_ulong(name_arg, offset_arg) + {} + bool check(THD *thd, set_var *var); }; @@ -225,7 +243,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); }; @@ -245,7 +263,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; @@ -271,7 +289,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); @@ -282,6 +300,7 @@ public: class sys_var_thd_enum :public sys_var_thd { +protected: ulong SV::*offset; TYPELIB *enum_names; public: @@ -301,11 +320,29 @@ 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; } }; +extern void fix_sql_mode_var(THD *thd, enum_var_type type); + +class sys_var_thd_sql_mode :public sys_var_thd_enum +{ +public: + sys_var_thd_sql_mode(const char *name_arg, ulong SV::*offset_arg) + :sys_var_thd_enum(name_arg, offset_arg, &sql_mode_typelib, + fix_sql_mode_var) + {} + bool check(THD *thd, set_var *var) + { + 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, LEX_STRING *base); +}; + + class sys_var_thd_bit :public sys_var_thd { sys_update_func update_func; @@ -325,7 +362,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); }; @@ -340,7 +377,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); }; @@ -351,7 +388,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); }; @@ -362,10 +399,11 @@ 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); }; +#ifndef EMBEDDED_LIBRARY class sys_var_slave_skip_counter :public sys_var { public: @@ -378,7 +416,7 @@ public: type() or value_ptr() */ }; - +#endif class sys_var_rand_seed1 :public sys_var { @@ -397,25 +435,134 @@ public: }; -class sys_var_thd_conv_charset :public sys_var_thd +class sys_var_collation :public sys_var_thd { public: - sys_var_thd_conv_charset(const char *name_arg) - :sys_var_thd(name_arg) - {} + sys_var_collation(const char *name_arg) :sys_var_thd(name_arg) {} bool check(THD *thd, set_var *var); - bool update(THD *thd, set_var *var); - SHOW_TYPE type() { return SHOW_CHAR; } - byte *value_ptr(THD *thd, enum_var_type type); +SHOW_TYPE type() { return SHOW_CHAR; } + bool check_update_type(Item_result type) + { + return type != STRING_RESULT; /* Only accept strings */ + } + bool check_default(enum_var_type type) { return 0; } + virtual void set_default(THD *thd, enum_var_type type)= 0; +}; + +class sys_var_character_set :public sys_var_thd +{ +public: + bool nullable; + sys_var_character_set(const char *name_arg) :sys_var_thd(name_arg) + { nullable= 0; } + bool check(THD *thd, set_var *var); +SHOW_TYPE type() { return SHOW_CHAR; } bool check_update_type(Item_result type) { return type != STRING_RESULT; /* Only accept strings */ } 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, 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; +}; + +class sys_var_character_set_client :public sys_var_character_set +{ +public: + sys_var_character_set_client(const char *name_arg) : + sys_var_character_set(name_arg) {} + void set_default(THD *thd, enum_var_type type); + CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type); +}; + +class sys_var_character_set_results :public sys_var_character_set +{ +public: + sys_var_character_set_results(const char *name_arg) : + sys_var_character_set(name_arg) + { nullable= 1; } + void set_default(THD *thd, enum_var_type type); + CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type); +}; + +class sys_var_character_set_server :public sys_var_character_set +{ +public: + sys_var_character_set_server(const char *name_arg) : + sys_var_character_set(name_arg) {} + void set_default(THD *thd, enum_var_type type); + CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type); +}; + +class sys_var_character_set_database :public sys_var_character_set +{ +public: + sys_var_character_set_database(const char *name_arg) : + sys_var_character_set(name_arg) {} + void set_default(THD *thd, enum_var_type type); + CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type); +}; + +class sys_var_character_set_connection :public sys_var_character_set +{ +public: + sys_var_character_set_connection(const char *name_arg) : + sys_var_character_set(name_arg) {} + void set_default(THD *thd, enum_var_type type); + CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type); +}; + +class sys_var_collation_connection :public sys_var_collation +{ +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, 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 +{ +public: + enum_var_type var_type; + SHOW_TYPE show_type; + sys_value_ptr_func value_ptr_func; + sys_var_readonly(const char *name_arg, enum_var_type type, + SHOW_TYPE show_type_arg, + sys_value_ptr_func value_ptr_func_arg) + :sys_var(name_arg), var_type(type), + show_type(show_type_arg), value_ptr_func(value_ptr_func_arg) + {} + bool update(THD *thd, set_var *var) { return 1; } + 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, LEX_STRING *base) + { + return (*value_ptr_func)(thd); + } + SHOW_TYPE type() { return show_type; } +}; + /**************************************************************************** Classes for parsing of the SET command ****************************************************************************/ @@ -440,12 +587,14 @@ public: enum_var_type type; union { - CONVERT *convert; + CHARSET_INFO *charset; ulong ulong_value; } save_result; + LEX_STRING base; /* for structs */ - set_var(enum_var_type type_arg, sys_var *var_arg, Item *value_arg) - :var(var_arg), type(type_arg) + set_var(enum_var_type type_arg, sys_var *var_arg, LEX_STRING *base_name_arg, + Item *value_arg) + :var(var_arg), type(type_arg), base(*base_name_arg) { /* If the set value is a field, change it to a string to allow things like @@ -454,7 +603,8 @@ public: if (value_arg && value_arg->type() == Item::FIELD_ITEM) { Item_field *item= (Item_field*) value_arg; - if (!(value=new Item_string(item->field_name, strlen(item->field_name)))) + if (!(value=new Item_string(item->field_name, strlen(item->field_name), + item->collation.collation))) value=value_arg; /* Give error message later */ } else @@ -493,6 +643,60 @@ public: }; +/* For SET NAMES and SET CHARACTER SET */ + +class set_var_collation_client: public set_var_base +{ + CHARSET_INFO *character_set_client; + CHARSET_INFO *character_set_results; + CHARSET_INFO *collation_connection; +public: + set_var_collation_client(CHARSET_INFO *client_coll_arg, + CHARSET_INFO *connection_coll_arg, + CHARSET_INFO *result_coll_arg) + :character_set_client(client_coll_arg), + character_set_results(result_coll_arg), + collation_connection(connection_coll_arg) + {} + int check(THD *thd); + int update(THD *thd); +}; + + +/* 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_memdup(name_arg, name_length, 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)); + } +}; + + +/* For sql_yacc */ +struct sys_var_with_base +{ + sys_var *var; + LEX_STRING base_name; +}; + /* Prototypes for helper functions */ @@ -502,5 +706,13 @@ void set_var_free(); 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); - -extern sys_var_str sys_charset; +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, + NAMED_LIST **found); +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); |