summaryrefslogtreecommitdiff
path: root/sql/set_var.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/set_var.h')
-rw-r--r--sql/set_var.h274
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);