diff options
author | Sergei Golubchik <sergii@pisem.net> | 2011-11-22 18:05:34 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2011-11-22 18:05:34 +0100 |
commit | b81d8b2e5ab7baa9623d0af002083057cda28a97 (patch) | |
tree | 0b2ebd731ba2cd0aea9454140b5f05b8673ec4ba | |
parent | d2755a2c9c109ddb4e2e0c9feda89431a6c4fd50 (diff) | |
download | mariadb-git-b81d8b2e5ab7baa9623d0af002083057cda28a97.tar.gz |
Add support for signed sysvars.
Make max_user_connections signed, with min allowed value being -1.
-rw-r--r-- | include/mysql/plugin.h | 10 | ||||
-rw-r--r-- | include/mysql/plugin_audit.h.pp | 5 | ||||
-rw-r--r-- | include/mysql/plugin_auth.h.pp | 5 | ||||
-rw-r--r-- | include/mysql/plugin_ftparser.h.pp | 5 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/max_user_connections_basic.result | 6 | ||||
-rw-r--r-- | mysql-test/t/user_limits.test | 1 | ||||
-rw-r--r-- | sql/item_func.cc | 62 | ||||
-rw-r--r-- | sql/set_var.cc | 2 | ||||
-rw-r--r-- | sql/set_var.h | 3 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | sql/sql_connect.cc | 2 | ||||
-rw-r--r-- | sql/sql_show.cc | 15 | ||||
-rw-r--r-- | sql/sys_vars.cc | 2 | ||||
-rw-r--r-- | sql/sys_vars.h | 86 |
14 files changed, 131 insertions, 75 deletions
diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h index 19601d85f94..4f70fe45d43 100644 --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h @@ -159,12 +159,18 @@ MARIA_DECLARE_PLUGIN__(NAME, \ */ enum enum_mysql_show_type { - SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG, - SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, + SHOW_UNDEF, SHOW_BOOL, SHOW_UINT, SHOW_ULONG, + SHOW_ULONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE, + SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, SHOW_always_last }; +/* backward compatibility mapping. */ +#define SHOW_INT SHOW_UINT +#define SHOW_LONG SHOW_ULONG +#define SHOW_LONGLONG SHOW_ULONGLONG + struct st_mysql_show_var { const char *name; char *value; diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index 0d248c5d39d..cdd9324a5f7 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -89,9 +89,10 @@ struct st_mysql_xid { typedef struct st_mysql_xid MYSQL_XID; enum enum_mysql_show_type { - SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG, - SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, + SHOW_UNDEF, SHOW_BOOL, SHOW_UINT, SHOW_ULONG, + SHOW_ULONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE, + SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, SHOW_always_last }; struct st_mysql_show_var { diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index f9df2bc94f8..e06494746dd 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -89,9 +89,10 @@ struct st_mysql_xid { typedef struct st_mysql_xid MYSQL_XID; enum enum_mysql_show_type { - SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG, - SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, + SHOW_UNDEF, SHOW_BOOL, SHOW_UINT, SHOW_ULONG, + SHOW_ULONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE, + SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, SHOW_always_last }; struct st_mysql_show_var { diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index f552b93a953..a990c62e8e9 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -89,9 +89,10 @@ struct st_mysql_xid { typedef struct st_mysql_xid MYSQL_XID; enum enum_mysql_show_type { - SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG, - SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, + SHOW_UNDEF, SHOW_BOOL, SHOW_UINT, SHOW_ULONG, + SHOW_ULONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE, + SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, SHOW_always_last }; struct st_mysql_show_var { diff --git a/mysql-test/suite/sys_vars/r/max_user_connections_basic.result b/mysql-test/suite/sys_vars/r/max_user_connections_basic.result index 26d82f3b215..c31498c1a66 100644 --- a/mysql-test/suite/sys_vars/r/max_user_connections_basic.result +++ b/mysql-test/suite/sys_vars/r/max_user_connections_basic.result @@ -51,7 +51,7 @@ Warnings: Warning 1292 Truncated incorrect max_user_connections value: '-1024' SELECT @@global.max_user_connections; @@global.max_user_connections -0 +-1 SET @@global.max_user_connections = 4294967296; Warnings: Warning 1292 Truncated incorrect max_user_connections value: '4294967296' @@ -59,11 +59,9 @@ SELECT @@global.max_user_connections; @@global.max_user_connections 2147483647 SET @@global.max_user_connections = -1; -Warnings: -Warning 1292 Truncated incorrect max_user_connections value: '-1' SELECT @@global.max_user_connections; @@global.max_user_connections -0 +-1 SET @@global.max_user_connections = 429496729500; Warnings: Warning 1292 Truncated incorrect max_user_connections value: '429496729500' diff --git a/mysql-test/t/user_limits.test b/mysql-test/t/user_limits.test index a8b549ca774..7c249f61686 100644 --- a/mysql-test/t/user_limits.test +++ b/mysql-test/t/user_limits.test @@ -1,4 +1,3 @@ -skip enable when max_user_connections can be negative # # Test behavior of various per-account limits (aka quotas) # diff --git a/sql/item_func.cc b/sql/item_func.cc index c771bfbf133..251ecd00242 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5491,16 +5491,15 @@ void Item_func_get_system_var::fix_length_and_dec() switch (var->show_type()) { - case SHOW_LONG: - case SHOW_INT: case SHOW_HA_ROWS: - unsigned_flag= TRUE; //var->show_type() != SHOW_INT; - collation.set_numeric(); - fix_char_length(MY_INT64_NUM_DECIMAL_DIGITS); - decimals=0; - break; - case SHOW_LONGLONG: + case SHOW_UINT: + case SHOW_ULONG: + case SHOW_ULONGLONG: unsigned_flag= TRUE; + /* fall through */ + case SHOW_SINT: + case SHOW_SLONG: + case SHOW_SLONGLONG: collation.set_numeric(); fix_char_length(MY_INT64_NUM_DECIMAL_DIGITS); decimals=0; @@ -5535,13 +5534,11 @@ void Item_func_get_system_var::fix_length_and_dec() break; case SHOW_BOOL: case SHOW_MY_BOOL: - unsigned_flag= FALSE; collation.set_numeric(); fix_char_length(1); decimals=0; break; case SHOW_DOUBLE: - unsigned_flag= FALSE; decimals= 6; collation.set_numeric(); fix_char_length(DBL_DIG + 6); @@ -5565,9 +5562,12 @@ enum Item_result Item_func_get_system_var::result_type() const { case SHOW_BOOL: case SHOW_MY_BOOL: - case SHOW_INT: - case SHOW_LONG: - case SHOW_LONGLONG: + case SHOW_SINT: + case SHOW_SLONG: + case SHOW_SLONGLONG: + case SHOW_UINT: + case SHOW_ULONG: + case SHOW_ULONGLONG: case SHOW_HA_ROWS: return INT_RESULT; case SHOW_CHAR: @@ -5589,9 +5589,12 @@ enum_field_types Item_func_get_system_var::field_type() const { case SHOW_BOOL: case SHOW_MY_BOOL: - case SHOW_INT: - case SHOW_LONG: - case SHOW_LONGLONG: + case SHOW_SINT: + case SHOW_SLONG: + case SHOW_SLONGLONG: + case SHOW_UINT: + case SHOW_ULONG: + case SHOW_ULONGLONG: case SHOW_HA_ROWS: return MYSQL_TYPE_LONGLONG; case SHOW_CHAR: @@ -5660,9 +5663,12 @@ longlong Item_func_get_system_var::val_int() switch (var->show_type()) { - case SHOW_INT: get_sys_var_safe (uint); - case SHOW_LONG: get_sys_var_safe (ulong); - case SHOW_LONGLONG: get_sys_var_safe (ulonglong); + case SHOW_SINT: get_sys_var_safe (int); + case SHOW_SLONG: get_sys_var_safe (long); + case SHOW_SLONGLONG:get_sys_var_safe (longlong); + case SHOW_UINT: get_sys_var_safe (uint); + case SHOW_ULONG: get_sys_var_safe (ulong); + case SHOW_ULONGLONG:get_sys_var_safe (ulonglong); case SHOW_HA_ROWS: get_sys_var_safe (ha_rows); case SHOW_BOOL: get_sys_var_safe (bool); case SHOW_MY_BOOL: get_sys_var_safe (my_bool); @@ -5763,9 +5769,12 @@ String* Item_func_get_system_var::val_str(String* str) break; } - case SHOW_INT: - case SHOW_LONG: - case SHOW_LONGLONG: + case SHOW_SINT: + case SHOW_SLONG: + case SHOW_SLONGLONG: + case SHOW_UINT: + case SHOW_ULONG: + case SHOW_ULONGLONG: case SHOW_HA_ROWS: case SHOW_BOOL: case SHOW_MY_BOOL: @@ -5855,9 +5864,12 @@ double Item_func_get_system_var::val_real() cache_present|= GET_SYS_VAR_CACHE_DOUBLE; return cached_dval; } - case SHOW_INT: - case SHOW_LONG: - case SHOW_LONGLONG: + case SHOW_SINT: + case SHOW_SLONG: + case SHOW_SLONGLONG: + case SHOW_UINT: + case SHOW_ULONG: + case SHOW_ULONGLONG: case SHOW_HA_ROWS: case SHOW_BOOL: case SHOW_MY_BOOL: diff --git a/sql/set_var.cc b/sql/set_var.cc index ce4d201672c..895facee6e9 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -308,7 +308,7 @@ void sys_var::do_deprecated_warning(THD *thd) bool throw_bounds_warning(THD *thd, const char *name, bool fixed, bool is_unsigned, longlong v) { - if (fixed || (!is_unsigned && v < 0)) + if (fixed) { char buf[22]; diff --git a/sql/set_var.h b/sql/set_var.h index 2c345f3af5f..e2e44ef65da 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -201,7 +201,8 @@ public: enum_var_type type; union ///< temp storage to hold a value between sys_var::check and ::update { - ulonglong ulonglong_value; ///< for all integer, set, enum sysvars + ulonglong ulonglong_value; ///< for unsigned integer, set, enum sysvars + longlong longlong_value; ///< for signed integer double double_value; ///< for Sys_var_double plugin_ref plugin; ///< for Sys_var_plugin Time_zone *time_zone; ///< for Sys_var_tz diff --git a/sql/sql_class.h b/sql/sql_class.h index d842aa39045..70f47521711 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -520,7 +520,7 @@ typedef struct system_variables ulong query_cache_type; ulong tx_isolation; ulong updatable_views_with_limit; - uint max_user_connections; + int max_user_connections; /** In slave thread we need to know in behalf of which thread the query is being run to replicate temp tables properly diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 6ab6f3237d7..bcffad06ad1 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -130,7 +130,7 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc) /* Root is not affected by the value of max_user_connections */ if (global_system_variables.max_user_connections && !uc->user_resources.user_conn && - global_system_variables.max_user_connections < (uint) uc->connections && + global_system_variables.max_user_connections < uc->connections && !(thd->security_ctx->master_access & SUPER_ACL)) { my_error(ER_TOO_MANY_USER_CONNECTIONS, MYF(0), uc->user); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index b7c3a29cace..5666225a9d1 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2367,14 +2367,14 @@ static bool show_status_array(THD *thd, const char *wild, case SHOW_LONG_STATUS: value= ((char *) status_var + (intptr) value); /* fall through */ - case SHOW_LONG: + case SHOW_ULONG: case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status() end= int10_to_str(*(long*) value, buff, 10); break; case SHOW_LONGLONG_STATUS: value= ((char *) status_var + (intptr) value); /* fall through */ - case SHOW_LONGLONG: + case SHOW_ULONGLONG: end= longlong10_to_str(*(longlong*) value, buff, 10); break; case SHOW_HA_ROWS: @@ -2386,9 +2386,18 @@ static bool show_status_array(THD *thd, const char *wild, case SHOW_MY_BOOL: end= strmov(buff, *(my_bool*) value ? "ON" : "OFF"); break; - case SHOW_INT: + case SHOW_UINT: end= int10_to_str((long) *(uint*) value, buff, 10); break; + case SHOW_SINT: + end= int10_to_str((long) *(uint*) value, buff, -10); + break; + case SHOW_SLONG: + end= int10_to_str(*(long*) value, buff, -10); + break; + case SHOW_SLONGLONG: + end= longlong10_to_str(*(longlong*) value, buff, -10); + break; case SHOW_HAVE: { SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 6314a296b33..ef0e01b6e4e 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1255,7 +1255,7 @@ static Sys_var_max_user_conn Sys_max_user_connections( "The maximum number of active connections for a single user " "(0 = no limit)", SESSION_VAR(max_user_connections), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(0, INT_MAX), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, + VALID_RANGE(-1, INT_MAX), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(if_checking_enabled)); static Sys_var_ulong Sys_max_tmp_tables( diff --git a/sql/sys_vars.h b/sql/sys_vars.h index 653c0d94dbe..e7c03bbf552 100644 --- a/sql/sys_vars.h +++ b/sql/sys_vars.h @@ -104,21 +104,22 @@ struct CMD_LINE }; /** - Sys_var_unsigned template is used to generate Sys_var_* classes - for variables that represent the value as an unsigned integer. - They are Sys_var_uint, Sys_var_ulong, Sys_var_harows, Sys_var_ulonglong. + Sys_var_integer template is used to generate Sys_var_* classes + for variables that represent the value as an integer number. + They are Sys_var_uint, Sys_var_ulong, Sys_var_harows, Sys_var_ulonglong, + Sys_var_int. An integer variable has a minimal and maximal values, and a "block_size" (any valid value of the variable must be divisible by the block_size). Class specific constructor arguments: min, max, block_size - Backing store: uint, ulong, ha_rows, ulonglong, depending on the Sys_var_* + Backing store: int, uint, ulong, ha_rows, ulonglong, depending on the class */ template <typename T, ulong ARGT, enum enum_mysql_show_type SHOWT> -class Sys_var_unsigned: public sys_var +class Sys_var_integer: public sys_var { public: - Sys_var_unsigned(const char *name_arg, + Sys_var_integer(const char *name_arg, const char *comment, int flag_args, ptrdiff_t off, size_t size, CMD_LINE getopt, T min_val, T max_val, T def_val, uint block_size, PolyLock *lock=0, @@ -147,24 +148,49 @@ public: } bool do_check(THD *thd, set_var *var) { - my_bool fixed= FALSE; - ulonglong uv; - longlong v; + my_bool fixed= FALSE, unused; + longlong v= var->value->val_int(); - v= var->value->val_int(); - if (var->value->unsigned_flag) - uv= (ulonglong) v; + if ((ARGT == GET_HA_ROWS) || (ARGT == GET_UINT) || + (ARGT == GET_ULONG) || (ARGT == GET_ULL)) + { + ulonglong uv; + + /* + if the value is signed and negative, + and a variable is unsigned, it is set to zero + */ + if ((fixed= (!var->value->unsigned_flag && v < 0))) + uv= 0; + else + uv= v; + + var->save_result.ulonglong_value= + getopt_ull_limit_value(uv, &option, &unused); + + if (max_var_ptr() && (T)var->save_result.ulonglong_value > *max_var_ptr()) + var->save_result.ulonglong_value= *max_var_ptr(); + + fixed= fixed || var->save_result.ulonglong_value != uv; + } else - uv= (ulonglong) (v < 0 ? 0 : v); + { + /* + if the value is unsigned and has the highest bit set + and a variable is signed, it is set to max signed value + */ + if ((fixed= (var->value->unsigned_flag && v < 0))) + v= LONGLONG_MAX; - var->save_result.ulonglong_value= - getopt_ull_limit_value(uv, &option, &fixed); + var->save_result.longlong_value= + getopt_ll_limit_value(v, &option, &unused); - if (max_var_ptr() && var->save_result.ulonglong_value > *max_var_ptr()) - var->save_result.ulonglong_value= *max_var_ptr(); + if (max_var_ptr() && (T)var->save_result.longlong_value > *max_var_ptr()) + var->save_result.longlong_value= *max_var_ptr(); - return throw_bounds_warning(thd, name.str, - var->save_result.ulonglong_value != uv, + fixed= fixed || var->save_result.longlong_value != v; + } + return throw_bounds_warning(thd, name.str, fixed, var->value->unsigned_flag, v); } bool session_update(THD *thd, set_var *var) @@ -191,10 +217,11 @@ public: } }; -typedef Sys_var_unsigned<uint, GET_UINT, SHOW_INT> Sys_var_uint; -typedef Sys_var_unsigned<ulong, GET_ULONG, SHOW_LONG> Sys_var_ulong; -typedef Sys_var_unsigned<ha_rows, GET_HA_ROWS, SHOW_HA_ROWS> Sys_var_harows; -typedef Sys_var_unsigned<ulonglong, GET_ULL, SHOW_LONGLONG> Sys_var_ulonglong; +typedef Sys_var_integer<int, GET_INT, SHOW_SINT> Sys_var_int; +typedef Sys_var_integer<uint, GET_UINT, SHOW_UINT> Sys_var_uint; +typedef Sys_var_integer<ulong, GET_ULONG, SHOW_ULONG> Sys_var_ulong; +typedef Sys_var_integer<ha_rows, GET_HA_ROWS, SHOW_HA_ROWS> Sys_var_harows; +typedef Sys_var_integer<ulonglong, GET_ULL, SHOW_ULONGLONG> Sys_var_ulonglong; /** Helper class for variables that take values from a TYPELIB @@ -883,7 +910,7 @@ public: Backing store: uint */ -class Sys_var_max_user_conn: public Sys_var_uint +class Sys_var_max_user_conn: public Sys_var_int { public: Sys_var_max_user_conn(const char *name_arg, @@ -895,7 +922,7 @@ public: on_check_function on_check_func=0, on_update_function on_update_func=0, uint deprecated_version=0, const char *substitute=0) - : Sys_var_uint(name_arg, comment, SESSION, off, size, getopt, + : Sys_var_int(name_arg, comment, SESSION, off, size, getopt, min_val, max_val, def_val, block_size, lock, binlog_status_arg, on_check_func, on_update_func, deprecated_version, substitute) @@ -1779,9 +1806,10 @@ public: #ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION template class List<set_var_base>; template class List_iterator_fast<set_var_base>; -template class Sys_var_unsigned<uint, GET_UINT, SHOW_INT>; -template class Sys_var_unsigned<ulong, GET_ULONG, SHOW_LONG>; -template class Sys_var_unsigned<ha_rows, GET_HA_ROWS, SHOW_HA_ROWS>; -template class Sys_var_unsigned<ulonglong, GET_ULL, SHOW_LONGLONG>; +template class Sys_var_integer<int, GET_INT, SHOW_SINT>; +template class Sys_var_integer<uint, GET_UINT, SHOW_INT>; +template class Sys_var_integer<ulong, GET_ULONG, SHOW_LONG>; +template class Sys_var_integer<ha_rows, GET_HA_ROWS, SHOW_HA_ROWS>; +template class Sys_var_integer<ulonglong, GET_ULL, SHOW_LONGLONG>; #endif |