1
0
mirror of https://github.com/MariaDB/server.git synced 2025-11-08 00:28:29 +03:00

MDEV-37784 Introduce @@new_mode variable

@@new_mode is a set of flags to control introduced features.
Flags are by default off.  Setting a flag in @@new_mode will introduce
a new different server behaviour and/or set of features.

We also introduce a new option 'hidden_values' into some system variable
types to hide options that we do not wish to show as options.

- Don't print hidden values in mysqld --help output.
- Make get_options() use the same logic as check_new_mode_value() does.
- Setting @@new_mode=ALL shouldn't give warnings.
This commit is contained in:
Rex Johnston
2025-10-02 12:53:58 +11:00
parent d71b2a7412
commit f7387cb13d
19 changed files with 351 additions and 25 deletions

View File

@@ -25,9 +25,10 @@ typedef struct st_typelib { /* Different types saved here */
const char *name; /* Name of typelib */
const char **type_names;
unsigned int *type_lengths;
const int *hidden_values;
} TYPELIB;
#define CREATE_TYPELIB_FOR(X) { (unsigned int)(sizeof(X)/sizeof(X[0])) - 1, "", X, NULL }
#define CREATE_TYPELIB_FOR(X) { (unsigned int)(sizeof(X)/sizeof(X[0])) - 1, "", X, NULL, NULL }
extern my_ulonglong find_typeset(const char *x, TYPELIB *typelib,
int *error_position);

View File

@@ -774,6 +774,9 @@ The following specify which files/extra groups are read (specified before remain
--net-write-timeout=#
Number of seconds to wait for a block to be written to a
connection before aborting the write
--new-mode=name Used to introduce new behavior to existing MariaDB
versions. Any combination of: FIX_DISK_TMPTABLE_COSTS, or
ALL to set all combinations
--note-verbosity=name
Verbosity level for note-warnings given to the user. See
also @@sql_notes. Any combination of: basic,
@@ -1861,6 +1864,7 @@ net-buffer-length 16384
net-read-timeout 30
net-retry-count 10
net-write-timeout 60
new-mode
note-verbosity basic,explain
old FALSE
old-mode UTF8_IS_UTF8MB3

View File

@@ -0,0 +1,83 @@
SET @global_start_value = @@global.new_mode;
SELECT @global_start_value;
@global_start_value
SET @session_start_value = @@session.new_mode;
SELECT @session_start_value;
@session_start_value
SET @@global.new_mode = "FIX_DISK_TMPTABLE_COSTS";
SELECT @@global.new_mode;
@@global.new_mode
FIX_DISK_TMPTABLE_COSTS
SELECT @@session.new_mode;
@@session.new_mode
SET @@global.new_mode = DEFAULT;
SELECT @@global.new_mode;
@@global.new_mode
SELECT @@session.new_mode;
@@session.new_mode
SET @@session.new_mode = "FIX_DISK_TMPTABLE_COSTS,TEST_WARNING1";
Warnings:
Warning 4209 'TEST_WARNING1' is default and ignored
SET @@session.new_mode = "FIX_DISK_TMPTABLE_COSTS,TEST_WARNING1,TEST_WARNING2";
Warnings:
Warning 4209 'TEST_WARNING1' is default and ignored
Warning 4209 'TEST_WARNING2' is default and ignored
SET @@session.new_mode = "FIX_DISK_TMPTABLE_COSTS,TEST_WARNING1,TEST_WARNING2,TEST_WARNING3";
ERROR 42000: Variable 'new_mode' can't be set to the value of 'TEST_WARNING3'
SET @@session.new_mode = "ALL";
select @@session.new_mode;
@@session.new_mode
FIX_DISK_TMPTABLE_COSTS
SET @@global.new_mode = NULL;
ERROR 42000: Variable 'new_mode' can't be set to the value of 'NULL'
SET @@global.new_mode = '';
SELECT @@global.new_mode;
@@global.new_mode
SET @@global.new_mode = ' ';
SELECT @@global.new_mode;
@@global.new_mode
SET @@session.new_mode = NULL;
ERROR 42000: Variable 'new_mode' can't be set to the value of 'NULL'
SET @@session.new_mode = '';
SELECT @@session.new_mode;
@@session.new_mode
SET @@session.new_mode = ' ';
SELECT @@session.new_mode;
@@session.new_mode
SET @@global.new_mode = OFF;
ERROR 42000: Variable 'new_mode' can't be set to the value of 'OFF'
SET @@session.new_mode = OFF;
ERROR 42000: Variable 'new_mode' can't be set to the value of 'OFF'
SET @debug_dbug_safe = @@global.debug_dbug;
SET @@global.debug_dbug = 'd,check_new_mode_mdev_37784';
create table t1 (a int);
insert into t1 values (1), (2);
create table t2 (b int);
insert into t2 values (3), (4);
select * from t1 where a in (select b from t2);
a
SET @@new_mode = "FIX_DISK_TMPTABLE_COSTS";
select * from t1 where a in (select b from t2);
a
Warnings:
Note 1003 YES
Note 1003 YES
drop table t1, t2;
SET @@global.debug_dbug = @debug_dbug_safe;
SET @@global.new_mode = @global_start_value;
SELECT @@global.new_mode;
@@global.new_mode
SET @@session.new_mode = @session_start_value;
SELECT @@session.new_mode;
@@session.new_mode

View File

@@ -2392,6 +2392,16 @@ NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME NEW_MODE
VARIABLE_SCOPE SESSION
VARIABLE_TYPE SET
VARIABLE_COMMENT Used to introduce new behavior to existing MariaDB versions
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST FIX_DISK_TMPTABLE_COSTS
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME NOTE_VERBOSITY
VARIABLE_SCOPE SESSION
VARIABLE_TYPE SET

View File

@@ -2602,6 +2602,16 @@ NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME NEW_MODE
VARIABLE_SCOPE SESSION
VARIABLE_TYPE SET
VARIABLE_COMMENT Used to introduce new behavior to existing MariaDB versions
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST FIX_DISK_TMPTABLE_COSTS
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME NOTE_VERBOSITY
VARIABLE_SCOPE SESSION
VARIABLE_TYPE SET

View File

@@ -0,0 +1,67 @@
--source include/load_sysvars.inc
--source include/have_debug.inc
SET @global_start_value = @@global.new_mode;
SELECT @global_start_value;
SET @session_start_value = @@session.new_mode;
SELECT @session_start_value;
SET @@global.new_mode = "FIX_DISK_TMPTABLE_COSTS";
SELECT @@global.new_mode;
SELECT @@session.new_mode;
SET @@global.new_mode = DEFAULT;
SELECT @@global.new_mode;
SELECT @@session.new_mode;
SET @@session.new_mode = "FIX_DISK_TMPTABLE_COSTS,TEST_WARNING1";
SET @@session.new_mode = "FIX_DISK_TMPTABLE_COSTS,TEST_WARNING1,TEST_WARNING2";
--Error ER_WRONG_VALUE_FOR_VAR
SET @@session.new_mode = "FIX_DISK_TMPTABLE_COSTS,TEST_WARNING1,TEST_WARNING2,TEST_WARNING3";
SET @@session.new_mode = "ALL";
select @@session.new_mode;
--Error ER_WRONG_VALUE_FOR_VAR
SET @@global.new_mode = NULL;
SET @@global.new_mode = '';
SELECT @@global.new_mode;
SET @@global.new_mode = ' ';
SELECT @@global.new_mode;
--Error ER_WRONG_VALUE_FOR_VAR
SET @@session.new_mode = NULL;
SET @@session.new_mode = '';
SELECT @@session.new_mode;
SET @@session.new_mode = ' ';
SELECT @@session.new_mode;
--Error ER_WRONG_VALUE_FOR_VAR
SET @@global.new_mode = OFF;
--Error ER_WRONG_VALUE_FOR_VAR
SET @@session.new_mode = OFF;
SET @debug_dbug_safe = @@global.debug_dbug;
SET @@global.debug_dbug = 'd,check_new_mode_mdev_37784';
create table t1 (a int);
insert into t1 values (1), (2);
create table t2 (b int);
insert into t2 values (3), (4);
select * from t1 where a in (select b from t2);
SET @@new_mode = "FIX_DISK_TMPTABLE_COSTS";
select * from t1 where a in (select b from t2);
drop table t1, t2;
SET @@global.debug_dbug = @debug_dbug_safe;
SET @@global.new_mode = @global_start_value;
SELECT @@global.new_mode;
SET @@session.new_mode = @session_start_value;
SELECT @@session.new_mode;

View File

@@ -1684,6 +1684,22 @@ void my_print_help(const struct my_option *options)
col= print_comment(optp->typelib->type_names[0], col, name_space, comment_space);
for (i= 1; i < count; i++)
{
my_bool skip_value= 0;
/* Do not print the value if it is listed in hidden_values */
if (optp->typelib->hidden_values)
{
for (const int *value= optp->typelib->hidden_values;
*value >= 0; value++)
{
if (*value == (int)i)
{
skip_value= 1;
break;
}
}
}
if (skip_value)
continue;
col= print_comment(", ", col, name_space, comment_space);
col= print_comment(optp->typelib->type_names[i], col, name_space, comment_space);
}

View File

@@ -155,7 +155,7 @@ const char *tx_isolation_names[]=
NullS};
TYPELIB tx_isolation_typelib= CREATE_TYPELIB_FOR(tx_isolation_names);
static TYPELIB known_extensions= {0,"known_exts", NULL, NULL};
static TYPELIB known_extensions= {0,"known_exts", NULL, NULL, NULL};
uint known_extensions_id= 0;

View File

@@ -301,7 +301,7 @@ static const char *tc_heuristic_recover_names[]=
static TYPELIB tc_heuristic_recover_typelib=
{
array_elements(tc_heuristic_recover_names)-1,"",
tc_heuristic_recover_names, NULL
tc_heuristic_recover_names, NULL, NULL
};
const char *first_keyword= "first";
@@ -8755,6 +8755,9 @@ static void option_error_reporter(enum loglevel level, const char *format, ...)
C_MODE_END
extern const char **new_mode_default_names;
/**
Get server options from the command line,
and perform related server initializations.
@@ -8813,6 +8816,8 @@ static int get_options(int *argc_ptr, char ***argv_ptr)
OLD_MODE_COMPAT_5_1_CHECKSUM);
}
check_new_mode_value(NULL, &global_system_variables.new_behavior);
if (global_system_variables.net_buffer_length >
global_system_variables.max_allowed_packet)
{

View File

@@ -2767,6 +2767,15 @@ get_tmp_table_costs(THD *thd, double row_count, uint row_size, bool blobs_used,
row_size+= sizeof(char*)*2;
row_size= MY_ALIGN(MY_MAX(row_size, sizeof(char*)) + 1, sizeof(char*));
/* remove this once TEST_NEW_MODE_FLAG is used elsewhere */
DBUG_EXECUTE_IF("check_new_mode_mdev_37784",
{
if (TEST_NEW_MODE_FLAG(thd, NEW_MODE_FIX_DISK_TMPTABLE_COSTS))
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_YES, "YES" );
}
});
if (row_count > thd->variables.max_heap_table_size / (double) row_size ||
blobs_used)
{

View File

@@ -1232,9 +1232,21 @@ int fill_sysvars(THD *thd, TABLE_LIST *tables, COND *cond)
strbuf.length(0);
for (i=0; i < tl->count; i++)
{
const char *name= tl->type_names[i];
strbuf.append(name, strlen(name));
strbuf.append(',');
bool show= TRUE;
if (tl->hidden_values)
{
for (uint j= 0; tl->hidden_values[j] >= 0; j++)
{
if (tl->hidden_values[j] == (int)i)
show= FALSE;
}
}
if (show)
{
const char *name= tl->type_names[i];
strbuf.append(name, strlen(name));
strbuf.append(',');
}
}
if (!strbuf.is_empty())
strbuf.chop();

View File

@@ -488,4 +488,6 @@ void free_engine_list(plugin_ref *list);
plugin_ref *copy_engine_list(plugin_ref *list);
plugin_ref *temp_copy_engine_list(THD *thd, plugin_ref *list);
char *pretty_print_engine_list(THD *thd, plugin_ref *list);
void check_new_mode_value(THD *thd, ulonglong *v);
#endif

View File

@@ -12297,3 +12297,8 @@ WARN_INDEX_HINTS_IGNORED
ukr "Підказки по використанню индексів ігноруются тому що вони несумісні з RETURNING"
ER_SIGNAL_SKIP_ROW_FROM_TRIGGER
eng "The row is skipped by a trigger implementation"
ER_WARN_DEFAULT_SYNTAX
chi "'%s' 默认并被忽略"
eng "'%s' is default and ignored"
ger "'%s' ist Standard und wird ignoriert"
spa "'%s' Es predeterminado e ignorado"

View File

@@ -216,6 +216,24 @@ enum enum_binlog_row_image {
void old_mode_deprecated_warnings(ulonglong v);
/*
Bits for @@new_mode -> thd->variables.new_behaviour system variable
See sys_vars.cc /new_mode_all_names
*/
#define NEW_MODE_FIX_DISK_TMPTABLE_COSTS (1 << 0)
#define NEW_MODE_MAX 1
/* Definitions above that have transitioned from new behaviour to default */
#define NOW_DEFAULT -1
#define NEW_MODE_TEST_WARNING1 NOW_DEFAULT
#define NEW_MODE_TEST_WARNING2 NOW_DEFAULT
#define TEST_NEW_MODE_FLAG(thd, flag) \
(flag == NOW_DEFAULT ? TRUE : thd->variables.new_behavior & flag)
extern char internal_table_name[2];
extern char empty_c_string[1];
extern MYSQL_PLUGIN_IMPORT const char **errmesg;
@@ -724,6 +742,7 @@ typedef struct system_variables
ulonglong optimizer_trace;
sql_mode_t sql_mode; ///< which non-standard SQL behaviour should be enabled
sql_mode_t old_behavior; ///< which old SQL behaviour should be enabled
sql_mode_t new_behavior; ///< which new SQL behaviour should be enabled
ulonglong option_bits; ///< OPTION_xxx constants, e.g. OPTION_PROFILING
ulonglong join_buff_space_limit;
ulonglong log_slow_filter;

View File

@@ -3194,25 +3194,25 @@ static const char *my_locale_ab_day_names_el_GR[8]=
static TYPELIB my_locale_typelib_month_names_el_GR=
{
array_elements(my_locale_month_names_el_GR) - 1,
"", my_locale_month_names_el_GR, NULL
"", my_locale_month_names_el_GR, NULL, NULL
};
static TYPELIB my_locale_typelib_ab_month_names_el_GR=
{
array_elements(my_locale_ab_month_names_el_GR)-1,
"", my_locale_ab_month_names_el_GR, NULL
"", my_locale_ab_month_names_el_GR, NULL, NULL
};
static TYPELIB my_locale_typelib_day_names_el_GR=
{
array_elements(my_locale_day_names_el_GR)-1,
"", my_locale_day_names_el_GR, NULL
"", my_locale_day_names_el_GR, NULL, NULL
};
static TYPELIB my_locale_typelib_ab_day_names_el_GR=
{
array_elements(my_locale_ab_day_names_el_GR) - 1,
"", my_locale_ab_day_names_el_GR, NULL
"", my_locale_ab_day_names_el_GR, NULL, NULL
};
MY_LOCALE my_locale_el_GR
@@ -3262,25 +3262,25 @@ static const char *my_locale_ab_day_names_rm_CH[8]=
static TYPELIB my_locale_typelib_month_names_rm_CH=
{
array_elements(my_locale_month_names_rm_CH) - 1,
"", my_locale_month_names_rm_CH, NULL
"", my_locale_month_names_rm_CH, NULL, NULL
};
static TYPELIB my_locale_typelib_ab_month_names_rm_CH=
{
array_elements(my_locale_ab_month_names_rm_CH) - 1,
"", my_locale_ab_month_names_rm_CH, NULL
"", my_locale_ab_month_names_rm_CH, NULL, NULL
};
static TYPELIB my_locale_typelib_day_names_rm_CH=
{
array_elements(my_locale_day_names_rm_CH) - 1,
"", my_locale_day_names_rm_CH, NULL
"", my_locale_day_names_rm_CH, NULL, NULL
};
static TYPELIB my_locale_typelib_ab_day_names_rm_CH=
{
array_elements(my_locale_ab_day_names_rm_CH) - 1,
"", my_locale_ab_day_names_rm_CH, NULL
"", my_locale_ab_day_names_rm_CH, NULL, NULL
};
MY_LOCALE my_locale_rm_CH

View File

@@ -4105,6 +4105,81 @@ static Sys_var_set Sys_old_behavior(
old_mode_names, DEFAULT(OLD_MODE_DEFAULT_VALUE),
NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(old_mode_deprecated));
/*
Current 'not yet default' @@new_mode flag names see sql_class.h /NEW_MODE_
These need to be be kept in the same order as the value of definitions above
*/
static const char *new_mode_all_names[]=
{
"FIX_DISK_TMPTABLE_COSTS",
"TEST_WARNING1", // Default from here, See NEW_MODE_MAX
"TEST_WARNING2",
0
};
static int new_mode_hidden_names[] =
{
1, // TEST_WARNING1
2, // TEST_WARNING2
-1 // End of list
};
/*
@@new_mode flag names that are now default and thus not configurable
see previous comment
*/
const char **new_mode_default_names= &new_mode_all_names[NEW_MODE_MAX];
/*
@brief
Emit warnings if the value of @@new_mode in *v contains flags that are
already included in the default behavior.
@param v INOUT Bitmap where bits represent indexes in new_mode_all_names
array.
Bits representing obsolete elements will be cleared.
*/
void check_new_mode_value(THD *thd, ulonglong *v)
{
ulonglong vl= *v >> NEW_MODE_MAX;
for (uint i=0; new_mode_default_names[i]; i++)
{
if ((1ULL<<i) & vl)
{
(*v)&= ~(1ULL << (i+NEW_MODE_MAX));
if (thd)
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WARN_DEFAULT_SYNTAX,
ER_THD(thd, ER_WARN_DEFAULT_SYNTAX),
new_mode_default_names[i], nullptr);
}
else
{
sql_print_warning("--new-mode='%s' is now default",
new_mode_default_names[i]);
}
}
}
}
static bool check_new_mode_var_value(sys_var *self, THD *thd, set_var *var)
{
check_new_mode_value(thd, &var->save_result.ulonglong_value);
return false;
}
static Sys_var_set Sys_new_behavior(
"new_mode",
"Used to introduce new behavior to existing MariaDB versions",
SESSION_VAR(new_behavior), CMD_LINE(REQUIRED_ARG),
new_mode_all_names, DEFAULT(0),
NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_new_mode_var_value), 0, 0,
new_mode_hidden_names);
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
#define SSL_OPT(X) CMD_LINE(REQUIRED_ARG,X)
#else

View File

@@ -320,7 +320,7 @@ public:
ulonglong def_val, PolyLock *lock,
enum binlog_status_enum binlog_status_arg,
on_check_function on_check_func, on_update_function on_update_func,
const char *substitute)
const char *substitute, int *hidden_values)
: sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id,
getopt.arg_type, show_val_type_arg, def_val, lock,
binlog_status_arg, on_check_func,
@@ -329,6 +329,7 @@ public:
for (typelib.count= 0; values[typelib.count]; typelib.count++) /*no-op */;
typelib.name="";
typelib.type_names= values;
typelib.hidden_values= hidden_values;
typelib.type_lengths= 0; // only used by Fields_enum and Field_set
option.typelib= &typelib;
}
@@ -390,7 +391,7 @@ public:
: Sys_var_typelib(name_arg, comment, flag_args, off, getopt,
SHOW_CHAR, values, def_val, lock,
binlog_status_arg, on_check_func, on_update_func,
substitute)
substitute, nullptr)
{
option.var_type|= GET_ENUM;
option.min_value= 0;
@@ -461,7 +462,7 @@ public:
: Sys_var_typelib(name_arg, comment, flag_args, off, getopt,
SHOW_MY_BOOL, bool_values, def_val, lock,
binlog_status_arg, on_check_func, on_update_func,
substitute)
substitute, nullptr)
{
option.var_type|= GET_BOOL;
global_var(my_bool)= def_val;
@@ -1407,11 +1408,11 @@ public:
enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
on_check_function on_check_func=0,
on_update_function on_update_func=0,
const char *substitute=0)
const char *substitute=0, int *hidden_values=nullptr)
: Sys_var_typelib(name_arg, comment, flag_args, off, getopt,
SHOW_CHAR, values, def_val, lock,
binlog_status_arg, on_check_func, on_update_func,
substitute)
substitute, hidden_values)
{
option.var_type|= GET_FLAGSET;
global_var(ulonglong)= def_val;
@@ -1520,11 +1521,11 @@ public:
enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
on_check_function on_check_func=0,
on_update_function on_update_func=0,
const char *substitute=0)
const char *substitute=0,int *hidden_values=nullptr)
: Sys_var_typelib(name_arg, comment, flag_args, off, getopt,
SHOW_CHAR, values, def_val, lock,
binlog_status_arg, on_check_func, on_update_func,
substitute)
substitute, hidden_values)
{
option.var_type|= GET_SET;
option.min_value= 0;
@@ -1573,6 +1574,13 @@ public:
!my_charset_latin1.strnncollsp(res->to_lex_cstring(), all_clex_str))
{
var->save_result.ulonglong_value= ((1ULL << (typelib.count)) -1);
if (typelib.hidden_values)
{
for (const int *p= typelib.hidden_values; *p >= 0; p++)
{
var->save_result.ulonglong_value &= ~(1ull << *p);
}
}
error_len= 0;
}
/*
@@ -1971,11 +1979,11 @@ public:
enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
on_check_function on_check_func=0,
on_update_function on_update_func=0,
const char *substitute=0)
const char *substitute=0, int *hidden_values=nullptr)
: Sys_var_typelib(name_arg, comment, flag_args, off, getopt,
SHOW_MY_BOOL, bool_values, def_val, lock,
binlog_status_arg, on_check_func, on_update_func,
substitute)
substitute, nullptr)
{
option.var_type|= GET_BIT;
reverse_semantics= my_count_bits(bitmask_arg) > 1;

View File

@@ -346,7 +346,7 @@ TYPELIB innodb_linux_aio_typelib = {
array_elements(innodb_linux_aio_names) - 1,
"innodb_linux_aio_typelib",
innodb_linux_aio_names,
NULL
NULL, NULL
};
#endif

View File

@@ -43,7 +43,7 @@ static const char *protocol_types[]= {"Auto", "Original", "Amazon", "Legacy", "P
TYPELIB s3_protocol_typelib= CREATE_TYPELIB_FOR(protocol_types);
static const char *providers[]= {"Default", "Amazon", "Huawei", NullS};
TYPELIB s3_provider_typelib = {array_elements(providers)-1,"",providers, NULL};
TYPELIB s3_provider_typelib = {array_elements(providers)-1,"",providers, NULL, NULL};
/******************************************************************************
Allocations handler for libmarias3