summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2011-11-22 18:05:34 +0100
committerSergei Golubchik <sergii@pisem.net>2011-11-22 18:05:34 +0100
commitb81d8b2e5ab7baa9623d0af002083057cda28a97 (patch)
tree0b2ebd731ba2cd0aea9454140b5f05b8673ec4ba
parentd2755a2c9c109ddb4e2e0c9feda89431a6c4fd50 (diff)
downloadmariadb-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.h10
-rw-r--r--include/mysql/plugin_audit.h.pp5
-rw-r--r--include/mysql/plugin_auth.h.pp5
-rw-r--r--include/mysql/plugin_ftparser.h.pp5
-rw-r--r--mysql-test/suite/sys_vars/r/max_user_connections_basic.result6
-rw-r--r--mysql-test/t/user_limits.test1
-rw-r--r--sql/item_func.cc62
-rw-r--r--sql/set_var.cc2
-rw-r--r--sql/set_var.h3
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_connect.cc2
-rw-r--r--sql/sql_show.cc15
-rw-r--r--sql/sys_vars.cc2
-rw-r--r--sql/sys_vars.h86
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