Commit 621caad3 authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-11917 enum/set command-line options aren't respecting max-*

settings.
parent d79bf000
...@@ -16,3 +16,33 @@ Warning 1292 Truncated incorrect max_join_size value: '40960' ...@@ -16,3 +16,33 @@ Warning 1292 Truncated incorrect max_join_size value: '40960'
SELECT @@session.max_join_size; SELECT @@session.max_join_size;
@@session.max_join_size @@session.max_join_size
8192 8192
SET @@session.use_stat_tables= COMPLEMENTARY;
SELECT @@session.use_stat_tables;
@@session.use_stat_tables
COMPLEMENTARY
SET @@session.use_stat_tables= PREFERABLY;
Warnings:
Warning 1292 Truncated incorrect use_stat_tables value: 'PREFERABLY'
SELECT @@session.use_stat_tables;
@@session.use_stat_tables
COMPLEMENTARY
SET @@session.use_stat_tables= 2;
Warnings:
Warning 1292 Truncated incorrect use_stat_tables value: '2'
SELECT @@session.use_stat_tables;
@@session.use_stat_tables
COMPLEMENTARY
SET @@session.sql_mode= 'REAL_AS_FLOAT';
SELECT @@session.sql_mode;
@@session.sql_mode
REAL_AS_FLOAT
SET @@session.sql_mode= 'REAL_AS_FLOAT,ANSI_QUOTES';
SELECT @@session.sql_mode;
@@session.sql_mode
REAL_AS_FLOAT,ANSI_QUOTES
SET @@session.sql_mode= 'ANSI_QUOTES,IGNORE_SPACE';
Warnings:
Warning 1292 Truncated incorrect sql_mode value: 'ANSI_QUOTES,IGNORE_SPACE'
SELECT @@session.sql_mode;
@@session.sql_mode
ANSI_QUOTES
--maximum-auto-increment-increment=8192 --maximum-auto-increment-increment=8192
--maximum-tmp-table-size=8192 --maximum-tmp-table-size=8192
--maximum-max-join-size=8192 --maximum-max-join-size=8192
--maximum-use-stat-tables=COMPLEMENTARY
--maximum-sql-mode='REAL_AS_FLOAT,ANSI_QUOTES'
...@@ -18,3 +18,22 @@ SELECT @@session.tmp_table_size; ...@@ -18,3 +18,22 @@ SELECT @@session.tmp_table_size;
SET @@session.max_join_size=40960; SET @@session.max_join_size=40960;
SELECT @@session.max_join_size; SELECT @@session.max_join_size;
#
# enum
#
SET @@session.use_stat_tables= COMPLEMENTARY;
SELECT @@session.use_stat_tables;
SET @@session.use_stat_tables= PREFERABLY;
SELECT @@session.use_stat_tables;
SET @@session.use_stat_tables= 2;
SELECT @@session.use_stat_tables;
#
# set
#
SET @@session.sql_mode= 'REAL_AS_FLOAT';
SELECT @@session.sql_mode;
SET @@session.sql_mode= 'REAL_AS_FLOAT,ANSI_QUOTES';
SELECT @@session.sql_mode;
SET @@session.sql_mode= 'ANSI_QUOTES,IGNORE_SPACE';
SELECT @@session.sql_mode;
...@@ -452,6 +452,22 @@ void sys_var::do_deprecated_warning(THD *thd) ...@@ -452,6 +452,22 @@ void sys_var::do_deprecated_warning(THD *thd)
@retval true on error, false otherwise (warning or ok) @retval true on error, false otherwise (warning or ok)
*/ */
bool throw_bounds_warning(THD *thd, const char *name,const char *v)
{
if (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES)
{
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, v);
return true;
}
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE,
ER_THD(thd, ER_TRUNCATED_WRONG_VALUE), name, v);
return false;
}
bool throw_bounds_warning(THD *thd, const char *name, bool throw_bounds_warning(THD *thd, const char *name,
bool fixed, bool is_unsigned, longlong v) bool fixed, bool is_unsigned, longlong v)
{ {
...@@ -469,9 +485,7 @@ bool throw_bounds_warning(THD *thd, const char *name, ...@@ -469,9 +485,7 @@ bool throw_bounds_warning(THD *thd, const char *name,
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buf); my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buf);
return true; return true;
} }
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, return throw_bounds_warning(thd, name, buf);
ER_TRUNCATED_WRONG_VALUE,
ER_THD(thd, ER_TRUNCATED_WRONG_VALUE), name, buf);
} }
return false; return false;
} }
...@@ -489,9 +503,7 @@ bool throw_bounds_warning(THD *thd, const char *name, bool fixed, double v) ...@@ -489,9 +503,7 @@ bool throw_bounds_warning(THD *thd, const char *name, bool fixed, double v)
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buf); my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buf);
return true; return true;
} }
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, return throw_bounds_warning(thd, name, buf);
ER_TRUNCATED_WRONG_VALUE,
ER_THD(thd, ER_TRUNCATED_WRONG_VALUE), name, buf);
} }
return false; return false;
} }
......
...@@ -243,6 +243,12 @@ class sys_var: protected Value_source // for double_from_string_with_check ...@@ -243,6 +243,12 @@ class sys_var: protected Value_source // for double_from_string_with_check
uchar *global_var_ptr() uchar *global_var_ptr()
{ return ((uchar*)&global_system_variables) + offset; } { return ((uchar*)&global_system_variables) + offset; }
void *max_var_ptr()
{
return scope() == SESSION ? (((uchar*)&max_system_variables) + offset) :
0;
}
friend class Session_sysvars_tracker; friend class Session_sysvars_tracker;
friend class Session_tracker; friend class Session_tracker;
}; };
......
...@@ -142,9 +142,10 @@ public: ...@@ -142,9 +142,10 @@ public:
option.min_value= min_val; option.min_value= min_val;
option.max_value= max_val; option.max_value= max_val;
option.block_size= block_size; option.block_size= block_size;
option.u_max_value= (uchar**)max_var_ptr(); if ((option.u_max_value= (uchar**) max_var_ptr()))
if (max_var_ptr()) {
*max_var_ptr()= max_val; *((T*) option.u_max_value)= max_val;
}
global_var(T)= def_val; global_var(T)= def_val;
SYSVAR_ASSERT(size == sizeof(T)); SYSVAR_ASSERT(size == sizeof(T));
...@@ -176,8 +177,8 @@ public: ...@@ -176,8 +177,8 @@ public:
var->save_result.ulonglong_value= var->save_result.ulonglong_value=
getopt_ull_limit_value(uv, &option, &unused); getopt_ull_limit_value(uv, &option, &unused);
if (max_var_ptr() && (T)var->save_result.ulonglong_value > *max_var_ptr()) if (max_var_ptr() && (T)var->save_result.ulonglong_value > get_max_var())
var->save_result.ulonglong_value= *max_var_ptr(); var->save_result.ulonglong_value= get_max_var();
fixed= fixed || var->save_result.ulonglong_value != uv; fixed= fixed || var->save_result.ulonglong_value != uv;
} }
...@@ -193,8 +194,8 @@ public: ...@@ -193,8 +194,8 @@ public:
var->save_result.longlong_value= var->save_result.longlong_value=
getopt_ll_limit_value(v, &option, &unused); getopt_ll_limit_value(v, &option, &unused);
if (max_var_ptr() && (T)var->save_result.longlong_value > *max_var_ptr()) if (max_var_ptr() && (T)var->save_result.longlong_value > get_max_var())
var->save_result.longlong_value= *max_var_ptr(); var->save_result.longlong_value= get_max_var();
fixed= fixed || var->save_result.longlong_value != v; fixed= fixed || var->save_result.longlong_value != v;
} }
...@@ -216,11 +217,7 @@ public: ...@@ -216,11 +217,7 @@ public:
void global_save_default(THD *thd, set_var *var) void global_save_default(THD *thd, set_var *var)
{ var->save_result.ulonglong_value= option.def_value; } { var->save_result.ulonglong_value= option.def_value; }
private: private:
T *max_var_ptr() T get_max_var() { return *((T*) max_var_ptr()); }
{
return scope() == SESSION ? (T*)(((uchar*)&max_system_variables) + offset)
: 0;
}
uchar *default_value_ptr(THD *thd) { return (uchar*) &option.def_value; } uchar *default_value_ptr(THD *thd) { return (uchar*) &option.def_value; }
}; };
...@@ -264,6 +261,9 @@ class Sys_var_typelib: public sys_var ...@@ -264,6 +261,9 @@ class Sys_var_typelib: public sys_var
{ {
protected: protected:
TYPELIB typelib; TYPELIB typelib;
virtual bool check_maximum(THD *thd, set_var *var,
const char *c_val, longlong i_val)
{ return FALSE; }
public: public:
Sys_var_typelib(const char *name_arg, Sys_var_typelib(const char *name_arg,
const char *comment, int flag_args, ptrdiff_t off, const char *comment, int flag_args, ptrdiff_t off,
...@@ -299,17 +299,14 @@ public: ...@@ -299,17 +299,14 @@ public:
return true; return true;
else else
var->save_result.ulonglong_value--; var->save_result.ulonglong_value--;
} return check_maximum(thd, var, res->ptr(), 0);
else
{
longlong tmp=var->value->val_int();
if (tmp < 0 || tmp >= typelib.count)
return true;
else
var->save_result.ulonglong_value= tmp;
} }
return false; longlong tmp=var->value->val_int();
if (tmp < 0 || tmp >= typelib.count)
return true;
var->save_result.ulonglong_value= tmp;
return check_maximum(thd, var, 0, tmp);
} }
}; };
...@@ -345,9 +342,25 @@ public: ...@@ -345,9 +342,25 @@ public:
{ {
option.var_type|= GET_ENUM; option.var_type|= GET_ENUM;
global_var(ulong)= def_val; global_var(ulong)= def_val;
if ((option.u_max_value= (uchar**)max_var_ptr()))
{
*((ulong *) option.u_max_value)= ULONG_MAX;
}
SYSVAR_ASSERT(def_val < typelib.count); SYSVAR_ASSERT(def_val < typelib.count);
SYSVAR_ASSERT(size == sizeof(ulong)); SYSVAR_ASSERT(size == sizeof(ulong));
} }
bool check_maximum(THD *thd, set_var *var,
const char *c_val, longlong i_val)
{
if (!max_var_ptr() ||
var->save_result.ulonglong_value <= get_max_var())
return FALSE;
var->save_result.ulonglong_value= get_max_var();
return c_val ? throw_bounds_warning(thd, name.str, c_val) :
throw_bounds_warning(thd, name.str, TRUE,
var->value->unsigned_flag, i_val);
}
bool session_update(THD *thd, set_var *var) bool session_update(THD *thd, set_var *var)
{ {
session_var(thd, ulong)= static_cast<ulong>(var->save_result.ulonglong_value); session_var(thd, ulong)= static_cast<ulong>(var->save_result.ulonglong_value);
...@@ -370,6 +383,8 @@ public: ...@@ -370,6 +383,8 @@ public:
{ return valptr(thd, global_var(ulong)); } { return valptr(thd, global_var(ulong)); }
uchar *default_value_ptr(THD *thd) uchar *default_value_ptr(THD *thd)
{ return valptr(thd, (ulong)option.def_value); } { return valptr(thd, (ulong)option.def_value); }
ulong get_max_var() { return *((ulong *) max_var_ptr()); }
}; };
/** /**
...@@ -1335,11 +1350,27 @@ public: ...@@ -1335,11 +1350,27 @@ public:
{ {
option.var_type|= GET_SET; option.var_type|= GET_SET;
global_var(ulonglong)= def_val; global_var(ulonglong)= def_val;
if ((option.u_max_value= (uchar**)max_var_ptr()))
{
*((ulonglong*) option.u_max_value)= ~0ULL;
}
SYSVAR_ASSERT(typelib.count > 0); SYSVAR_ASSERT(typelib.count > 0);
SYSVAR_ASSERT(typelib.count <= 64); SYSVAR_ASSERT(typelib.count <= 64);
SYSVAR_ASSERT(def_val <= my_set_bits(typelib.count)); SYSVAR_ASSERT(def_val <= my_set_bits(typelib.count));
SYSVAR_ASSERT(size == sizeof(ulonglong)); SYSVAR_ASSERT(size == sizeof(ulonglong));
} }
bool check_maximum(THD *thd, set_var *var,
const char *c_val, longlong i_val)
{
if (!max_var_ptr() ||
(var->save_result.ulonglong_value & ~(get_max_var())) == 0)
return FALSE;
var->save_result.ulonglong_value&= get_max_var();
return c_val ? throw_bounds_warning(thd, name.str, c_val) :
throw_bounds_warning(thd, name.str, TRUE,
var->value->unsigned_flag, i_val);
}
bool do_check(THD *thd, set_var *var) bool do_check(THD *thd, set_var *var)
{ {
char buff[STRING_BUFFER_USUAL_SIZE]; char buff[STRING_BUFFER_USUAL_SIZE];
...@@ -1347,41 +1378,37 @@ public: ...@@ -1347,41 +1378,37 @@ public:
if (var->value->result_type() == STRING_RESULT) if (var->value->result_type() == STRING_RESULT)
{ {
char *error;
uint error_len;
bool not_used;
if (!(res=var->value->val_str_ascii(&str))) if (!(res=var->value->val_str_ascii(&str)))
return true; return true;
else
{
char *error;
uint error_len;
bool not_used;
var->save_result.ulonglong_value= var->save_result.ulonglong_value=
find_set(&typelib, res->ptr(), res->length(), NULL, find_set(&typelib, res->ptr(), res->length(), NULL,
&error, &error_len, &not_used); &error, &error_len, &not_used);
/* /*
note, we only issue an error if error_len > 0. note, we only issue an error if error_len > 0.
That is even while empty (zero-length) values are considered That is even while empty (zero-length) values are considered
errors by find_set(), these errors are ignored here errors by find_set(), these errors are ignored here
*/ */
if (error_len) if (error_len)
{ {
ErrConvString err(error, error_len, res->charset()); ErrConvString err(error, error_len, res->charset());
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, err.ptr()); my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, err.ptr());
return true;
}
}
}
else
{
longlong tmp=var->value->val_int();
if ((tmp < 0 && ! var->value->unsigned_flag)
|| (ulonglong)tmp > my_set_bits(typelib.count))
return true; return true;
else }
var->save_result.ulonglong_value= tmp; return check_maximum(thd, var, res->ptr(), 0);
} }
return false; longlong tmp=var->value->val_int();
if ((tmp < 0 && ! var->value->unsigned_flag)
|| (ulonglong)tmp > my_set_bits(typelib.count))
return true;
var->save_result.ulonglong_value= tmp;
return check_maximum(thd, var, 0, tmp);
} }
bool session_update(THD *thd, set_var *var) bool session_update(THD *thd, set_var *var)
{ {
...@@ -1405,6 +1432,8 @@ public: ...@@ -1405,6 +1432,8 @@ public:
{ return valptr(thd, global_var(ulonglong)); } { return valptr(thd, global_var(ulonglong)); }
uchar *default_value_ptr(THD *thd) uchar *default_value_ptr(THD *thd)
{ return valptr(thd, option.def_value); } { return valptr(thd, option.def_value); }
ulonglong get_max_var() { return *((ulonglong*) max_var_ptr()); }
}; };
/** /**
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <sql_priv.h> #include <sql_priv.h>
#include "set_var.h" #include "set_var.h"
extern bool throw_bounds_warning(THD *thd, const char *name,const char *v);
extern bool throw_bounds_warning(THD *thd, const char *name, extern bool throw_bounds_warning(THD *thd, const char *name,
bool fixed, bool is_unsigned, longlong v); bool fixed, bool is_unsigned, longlong v);
extern bool throw_bounds_warning(THD *thd, const char *name, bool fixed, extern bool throw_bounds_warning(THD *thd, const char *name, bool fixed,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment