Commit 06142cd5 authored by Gleb Shchepa's avatar Gleb Shchepa

Bug #42778: delete order by null global variable causes

            assertion .\filesort.cc, line 797

A query with the "ORDER BY @@some_system_variable" clause,
where @@some_system_variable is NULL, causes assertion
failure in the filesort procedures.

The reason of the failure is in the value of
Item_func_get_system_var::maybe_null: it was unconditionally
set to false even if the value of a variable was NULL.


mysql-test/r/variables.result:
  Added test case for bug #42778.
mysql-test/suite/sys_vars/r/innodb_data_home_dir_basic.result:
  Updated test case for bug #42778:
  system variables were NOT NULL, now they are nullable.
mysql-test/suite/sys_vars/r/innodb_flush_method_basic.result:
  Updated test case for bug #42778:
  system variables were NOT NULL, now they are nullable.
mysql-test/suite/sys_vars/r/rpl_init_slave_func.result:
  Updated test case for bug #42778:
  system variables were NOT NULL, now they are nullable.
mysql-test/suite/sys_vars/r/ssl_capath_basic.result:
  Updated test case for bug #42778:
  system variables were NOT NULL, now they are nullable.
mysql-test/suite/sys_vars/r/ssl_cipher_basic.result:
  Updated test case for bug #42778:
  system variables were NOT NULL, now they are nullable.
mysql-test/suite/sys_vars/t/innodb_data_home_dir_basic.test:
  Updated test case for bug #42778:
  system variables were NOT NULL, now they are nullable.
mysql-test/suite/sys_vars/t/innodb_flush_method_basic.test:
  Updated test case for bug #42778:
  system variables were NOT NULL, now they are nullable.
mysql-test/suite/sys_vars/t/ssl_capath_basic.test:
  Updated test case for bug #42778:
  system variables were NOT NULL, now they are nullable.
mysql-test/suite/sys_vars/t/ssl_cipher_basic.test:
  Updated test case for bug #42778:
  system variables were NOT NULL, now they are nullable.
mysql-test/t/variables.test:
  Added test case for bug #42778.
sql/item.cc:
  Bug #42778: delete order by null global variable causes
              assertion .\filesort.cc, line 797
  
  The longlong_from_string_with_check function has been modified
  to skip unwanted warnings: now it uses the THD::no_errors
  flag to suppress warnings.
  The Item_func_get_system_var::update_null_value method
  sets the no_error flag.
sql/item_func.cc:
  Bug #42778: delete order by null global variable causes
              assertion .\filesort.cc, line 797
  
  1. The Item_func_get_system_var::fix_length_and_dec method
     has been modified to make system variables truly nullable.
  
  2. The Item_func_get_system_var::update_null_value method
     method has been overloaded with a simple wrapper (like
     Item_field::update_null_value) to suppress unwanted warnings
     from Item_func_get_system_var::val_int() calls on non-numeric
     variable values: the Item_func_get_system_var::update_null_value
     method sets and restores THD::no_errors flag for a nested
     call of the longlong_from_string_with_check function.
sql/item_func.h:
  Bug #42778: delete order by null global variable causes
              assertion .\filesort.cc, line 797
  
  The Item_func_get_system_var::update_null_value method
  method has been overloaded.
parent 42b3d8c7
......@@ -1436,7 +1436,7 @@ Warnings:
Warning 1292 Truncated incorrect auto_increment_offset value: '0'
select @@storage_engine;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def @@storage_engine 253 6 6 N 1 31 8
def @@storage_engine 253 6 6 Y 0 31 8
@@storage_engine
MyISAM
SET @old_server_id = @@GLOBAL.server_id;
......@@ -1467,4 +1467,23 @@ SELECT @@GLOBAL.server_id;
@@GLOBAL.server_id
0
SET GLOBAL server_id = @old_server_id;
SELECT @@GLOBAL.INIT_FILE, @@GLOBAL.INIT_FILE IS NULL;
@@GLOBAL.INIT_FILE @@GLOBAL.INIT_FILE IS NULL
NULL 1
SELECT @@GLOBAL.REPORT_HOST, @@GLOBAL.REPORT_HOST IS NULL;
@@GLOBAL.REPORT_HOST @@GLOBAL.REPORT_HOST IS NULL
NULL 1
SELECT @@GLOBAL.REPORT_PASSWORD, @@GLOBAL.REPORT_PASSWORD IS NULL;
@@GLOBAL.REPORT_PASSWORD @@GLOBAL.REPORT_PASSWORD IS NULL
NULL 1
SELECT @@GLOBAL.REPORT_USER, @@GLOBAL.REPORT_USER IS NULL;
@@GLOBAL.REPORT_USER @@GLOBAL.REPORT_USER IS NULL
NULL 1
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES ();
SET @bug42778= @@sql_safe_updates;
SET @@sql_safe_updates= 0;
DELETE FROM t1 ORDER BY (@@GLOBAL.INIT_FILE) ASC LIMIT 10;
SET @@sql_safe_updates= @bug42778;
DROP TABLE t1;
End of 5.1 tests
'#---------------------BS_STVARS_025_01----------------------#'
SELECT COUNT(@@GLOBAL.innodb_data_home_dir);
COUNT(@@GLOBAL.innodb_data_home_dir)
1
1 Expected
0
0 Expected
'#---------------------BS_STVARS_025_02----------------------#'
SET @@GLOBAL.innodb_data_home_dir=1;
ERROR HY000: Variable 'innodb_data_home_dir' is a read only variable
Expected error 'Read only variable'
SELECT COUNT(@@GLOBAL.innodb_data_home_dir);
COUNT(@@GLOBAL.innodb_data_home_dir)
1
1 Expected
0
0 Expected
'#---------------------BS_STVARS_025_03----------------------#'
SELECT @@GLOBAL.innodb_data_home_dir = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
......@@ -20,8 +20,8 @@ NULL
1 Expected
SELECT COUNT(@@GLOBAL.innodb_data_home_dir);
COUNT(@@GLOBAL.innodb_data_home_dir)
1
1 Expected
0
0 Expected
SELECT COUNT(VARIABLE_VALUE)
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='innodb_data_home_dir';
......@@ -36,8 +36,8 @@ NULL
'#---------------------BS_STVARS_025_05----------------------#'
SELECT COUNT(@@innodb_data_home_dir);
COUNT(@@innodb_data_home_dir)
1
1 Expected
0
0 Expected
SELECT COUNT(@@local.innodb_data_home_dir);
ERROR HY000: Variable 'innodb_data_home_dir' is a GLOBAL variable
Expected error 'Variable is a GLOBAL variable'
......@@ -46,8 +46,8 @@ ERROR HY000: Variable 'innodb_data_home_dir' is a GLOBAL variable
Expected error 'Variable is a GLOBAL variable'
SELECT COUNT(@@GLOBAL.innodb_data_home_dir);
COUNT(@@GLOBAL.innodb_data_home_dir)
1
1 Expected
0
0 Expected
SELECT innodb_data_home_dir = @@SESSION.innodb_data_home_dir;
ERROR 42S22: Unknown column 'innodb_data_home_dir' in 'field list'
Expected error 'Readonly variable'
'#---------------------BS_STVARS_029_01----------------------#'
SELECT COUNT(@@GLOBAL.innodb_flush_method);
COUNT(@@GLOBAL.innodb_flush_method)
1
1 Expected
0
0 Expected
'#---------------------BS_STVARS_029_02----------------------#'
SET @@GLOBAL.innodb_flush_method=1;
ERROR HY000: Variable 'innodb_flush_method' is a read only variable
Expected error 'Read only variable'
SELECT COUNT(@@GLOBAL.innodb_flush_method);
COUNT(@@GLOBAL.innodb_flush_method)
1
1 Expected
0
0 Expected
'#---------------------BS_STVARS_029_03----------------------#'
SELECT @@GLOBAL.innodb_flush_method = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
......@@ -20,8 +20,8 @@ NULL
1 Expected
SELECT COUNT(@@GLOBAL.innodb_flush_method);
COUNT(@@GLOBAL.innodb_flush_method)
1
1 Expected
0
0 Expected
SELECT COUNT(VARIABLE_VALUE)
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='innodb_flush_method';
......@@ -36,8 +36,8 @@ NULL
'#---------------------BS_STVARS_029_05----------------------#'
SELECT COUNT(@@innodb_flush_method);
COUNT(@@innodb_flush_method)
1
1 Expected
0
0 Expected
SELECT COUNT(@@local.innodb_flush_method);
ERROR HY000: Variable 'innodb_flush_method' is a GLOBAL variable
Expected error 'Variable is a GLOBAL variable'
......@@ -46,8 +46,8 @@ ERROR HY000: Variable 'innodb_flush_method' is a GLOBAL variable
Expected error 'Variable is a GLOBAL variable'
SELECT COUNT(@@GLOBAL.innodb_flush_method);
COUNT(@@GLOBAL.innodb_flush_method)
1
1 Expected
0
0 Expected
SELECT innodb_flush_method = @@SESSION.innodb_flush_method;
ERROR 42S22: Unknown column 'innodb_flush_method' in 'field list'
Expected error 'Readonly variable'
......@@ -12,7 +12,7 @@ DROP TABLE IF EXISTS t1;
CREATE TEMPORARY TABLE t1 AS SELECT @@global.init_slave AS my_column;
DESCRIBE t1;
Field Type Null Key Default Extra
my_column varchar(59) NO
my_column varchar(59) YES NULL
DROP TABLE t1;
SELECT @@global.init_slave = 'SET @@global.max_connections = @@global.max_connections + 1';
@@global.init_slave = 'SET @@global.max_connections = @@global.max_connections + 1'
......
'#---------------------BS_STVARS_046_01----------------------#'
SELECT COUNT(@@GLOBAL.ssl_capath);
COUNT(@@GLOBAL.ssl_capath)
1
1 Expected
0
0 Expected
'#---------------------BS_STVARS_046_02----------------------#'
SET @@GLOBAL.ssl_capath=1;
ERROR HY000: Variable 'ssl_capath' is a read only variable
Expected error 'Read only variable'
SELECT COUNT(@@GLOBAL.ssl_capath);
COUNT(@@GLOBAL.ssl_capath)
1
1 Expected
0
0 Expected
'#---------------------BS_STVARS_046_03----------------------#'
SELECT @@GLOBAL.ssl_capath = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
......@@ -20,8 +20,8 @@ NULL
1 Expected
SELECT COUNT(@@GLOBAL.ssl_capath);
COUNT(@@GLOBAL.ssl_capath)
1
1 Expected
0
0 Expected
SELECT COUNT(VARIABLE_VALUE)
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='ssl_capath';
......@@ -36,8 +36,8 @@ NULL
'#---------------------BS_STVARS_046_05----------------------#'
SELECT COUNT(@@ssl_capath);
COUNT(@@ssl_capath)
1
1 Expected
0
0 Expected
SELECT COUNT(@@local.ssl_capath);
ERROR HY000: Variable 'ssl_capath' is a GLOBAL variable
Expected error 'Variable is a GLOBAL variable'
......@@ -46,8 +46,8 @@ ERROR HY000: Variable 'ssl_capath' is a GLOBAL variable
Expected error 'Variable is a GLOBAL variable'
SELECT COUNT(@@GLOBAL.ssl_capath);
COUNT(@@GLOBAL.ssl_capath)
1
1 Expected
0
0 Expected
SELECT ssl_capath = @@SESSION.ssl_capath;
ERROR 42S22: Unknown column 'ssl_capath' in 'field list'
Expected error 'Readonly variable'
'#---------------------BS_STVARS_048_01----------------------#'
SELECT COUNT(@@GLOBAL.ssl_cipher);
COUNT(@@GLOBAL.ssl_cipher)
1
1 Expected
0
0 Expected
'#---------------------BS_STVARS_048_02----------------------#'
SET @@GLOBAL.ssl_cipher=1;
ERROR HY000: Variable 'ssl_cipher' is a read only variable
Expected error 'Read only variable'
SELECT COUNT(@@GLOBAL.ssl_cipher);
COUNT(@@GLOBAL.ssl_cipher)
1
1 Expected
0
0 Expected
'#---------------------BS_STVARS_048_03----------------------#'
SELECT @@GLOBAL.ssl_cipher = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
......@@ -20,8 +20,8 @@ NULL
1 Expected
SELECT COUNT(@@GLOBAL.ssl_cipher);
COUNT(@@GLOBAL.ssl_cipher)
1
1 Expected
0
0 Expected
SELECT COUNT(VARIABLE_VALUE)
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='ssl_cipher';
......@@ -36,8 +36,8 @@ NULL
'#---------------------BS_STVARS_048_05----------------------#'
SELECT COUNT(@@ssl_cipher);
COUNT(@@ssl_cipher)
1
1 Expected
0
0 Expected
SELECT COUNT(@@local.ssl_cipher);
ERROR HY000: Variable 'ssl_cipher' is a GLOBAL variable
Expected error 'Variable is a GLOBAL variable'
......@@ -46,8 +46,8 @@ ERROR HY000: Variable 'ssl_cipher' is a GLOBAL variable
Expected error 'Variable is a GLOBAL variable'
SELECT COUNT(@@GLOBAL.ssl_cipher);
COUNT(@@GLOBAL.ssl_cipher)
1
1 Expected
0
0 Expected
SELECT ssl_cipher = @@SESSION.ssl_cipher;
ERROR 42S22: Unknown column 'ssl_cipher' in 'field list'
Expected error 'Readonly variable'
......@@ -29,7 +29,7 @@
# Displaying default value #
####################################################################
SELECT COUNT(@@GLOBAL.innodb_data_home_dir);
--echo 1 Expected
--echo 0 Expected
--echo '#---------------------BS_STVARS_025_02----------------------#'
......@@ -42,7 +42,7 @@ SET @@GLOBAL.innodb_data_home_dir=1;
--echo Expected error 'Read only variable'
SELECT COUNT(@@GLOBAL.innodb_data_home_dir);
--echo 1 Expected
--echo 0 Expected
......@@ -58,7 +58,7 @@ WHERE VARIABLE_NAME='innodb_data_home_dir';
--echo 1 Expected
SELECT COUNT(@@GLOBAL.innodb_data_home_dir);
--echo 1 Expected
--echo 0 Expected
SELECT COUNT(VARIABLE_VALUE)
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
......@@ -82,7 +82,7 @@ SELECT @@innodb_data_home_dir = @@GLOBAL.innodb_data_home_dir;
################################################################################
SELECT COUNT(@@innodb_data_home_dir);
--echo 1 Expected
--echo 0 Expected
--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
SELECT COUNT(@@local.innodb_data_home_dir);
......@@ -93,7 +93,7 @@ SELECT COUNT(@@SESSION.innodb_data_home_dir);
--echo Expected error 'Variable is a GLOBAL variable'
SELECT COUNT(@@GLOBAL.innodb_data_home_dir);
--echo 1 Expected
--echo 0 Expected
--Error ER_BAD_FIELD_ERROR
SELECT innodb_data_home_dir = @@SESSION.innodb_data_home_dir;
......
......@@ -29,7 +29,7 @@
# Displaying default value #
####################################################################
SELECT COUNT(@@GLOBAL.innodb_flush_method);
--echo 1 Expected
--echo 0 Expected
--echo '#---------------------BS_STVARS_029_02----------------------#'
......@@ -42,7 +42,7 @@ SET @@GLOBAL.innodb_flush_method=1;
--echo Expected error 'Read only variable'
SELECT COUNT(@@GLOBAL.innodb_flush_method);
--echo 1 Expected
--echo 0 Expected
......@@ -58,7 +58,7 @@ WHERE VARIABLE_NAME='innodb_flush_method';
--echo 1 Expected
SELECT COUNT(@@GLOBAL.innodb_flush_method);
--echo 1 Expected
--echo 0 Expected
SELECT COUNT(VARIABLE_VALUE)
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
......@@ -82,7 +82,7 @@ SELECT @@innodb_flush_method = @@GLOBAL.innodb_flush_method;
################################################################################
SELECT COUNT(@@innodb_flush_method);
--echo 1 Expected
--echo 0 Expected
--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
SELECT COUNT(@@local.innodb_flush_method);
......@@ -93,7 +93,7 @@ SELECT COUNT(@@SESSION.innodb_flush_method);
--echo Expected error 'Variable is a GLOBAL variable'
SELECT COUNT(@@GLOBAL.innodb_flush_method);
--echo 1 Expected
--echo 0 Expected
--Error ER_BAD_FIELD_ERROR
SELECT innodb_flush_method = @@SESSION.innodb_flush_method;
......
......@@ -27,7 +27,7 @@
# Displaying default value #
####################################################################
SELECT COUNT(@@GLOBAL.ssl_capath);
--echo 1 Expected
--echo 0 Expected
--echo '#---------------------BS_STVARS_046_02----------------------#'
......@@ -40,7 +40,7 @@ SET @@GLOBAL.ssl_capath=1;
--echo Expected error 'Read only variable'
SELECT COUNT(@@GLOBAL.ssl_capath);
--echo 1 Expected
--echo 0 Expected
......@@ -56,7 +56,7 @@ WHERE VARIABLE_NAME='ssl_capath';
--echo 1 Expected
SELECT COUNT(@@GLOBAL.ssl_capath);
--echo 1 Expected
--echo 0 Expected
SELECT COUNT(VARIABLE_VALUE)
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
......@@ -80,7 +80,7 @@ SELECT @@ssl_capath = @@GLOBAL.ssl_capath;
################################################################################
SELECT COUNT(@@ssl_capath);
--echo 1 Expected
--echo 0 Expected
--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
SELECT COUNT(@@local.ssl_capath);
......@@ -91,7 +91,7 @@ SELECT COUNT(@@SESSION.ssl_capath);
--echo Expected error 'Variable is a GLOBAL variable'
SELECT COUNT(@@GLOBAL.ssl_capath);
--echo 1 Expected
--echo 0 Expected
--Error ER_BAD_FIELD_ERROR
SELECT ssl_capath = @@SESSION.ssl_capath;
......
......@@ -27,7 +27,7 @@
# Displaying default value #
####################################################################
SELECT COUNT(@@GLOBAL.ssl_cipher);
--echo 1 Expected
--echo 0 Expected
--echo '#---------------------BS_STVARS_048_02----------------------#'
......@@ -40,7 +40,7 @@ SET @@GLOBAL.ssl_cipher=1;
--echo Expected error 'Read only variable'
SELECT COUNT(@@GLOBAL.ssl_cipher);
--echo 1 Expected
--echo 0 Expected
......@@ -56,7 +56,7 @@ WHERE VARIABLE_NAME='ssl_cipher';
--echo 1 Expected
SELECT COUNT(@@GLOBAL.ssl_cipher);
--echo 1 Expected
--echo 0 Expected
SELECT COUNT(VARIABLE_VALUE)
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
......@@ -80,7 +80,7 @@ SELECT @@ssl_cipher = @@GLOBAL.ssl_cipher;
################################################################################
SELECT COUNT(@@ssl_cipher);
--echo 1 Expected
--echo 0 Expected
--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
SELECT COUNT(@@local.ssl_cipher);
......@@ -91,7 +91,7 @@ SELECT COUNT(@@SESSION.ssl_cipher);
--echo Expected error 'Variable is a GLOBAL variable'
SELECT COUNT(@@GLOBAL.ssl_cipher);
--echo 1 Expected
--echo 0 Expected
--Error ER_BAD_FIELD_ERROR
SELECT ssl_cipher = @@SESSION.ssl_cipher;
......
......@@ -1201,4 +1201,23 @@ SET GLOBAL server_id = -1;
SELECT @@GLOBAL.server_id;
SET GLOBAL server_id = @old_server_id;
#
# Bug #42778: delete order by null global variable causes
# assertion .\filesort.cc, line 797
#
SELECT @@GLOBAL.INIT_FILE, @@GLOBAL.INIT_FILE IS NULL;
SELECT @@GLOBAL.REPORT_HOST, @@GLOBAL.REPORT_HOST IS NULL;
SELECT @@GLOBAL.REPORT_PASSWORD, @@GLOBAL.REPORT_PASSWORD IS NULL;
SELECT @@GLOBAL.REPORT_USER, @@GLOBAL.REPORT_USER IS NULL;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES ();
SET @bug42778= @@sql_safe_updates;
SET @@sql_safe_updates= 0;
DELETE FROM t1 ORDER BY (@@GLOBAL.INIT_FILE) ASC LIMIT 10;
SET @@sql_safe_updates= @bug42778;
DROP TABLE t1;
--echo End of 5.1 tests
......@@ -2472,8 +2472,9 @@ longlong_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end)
TODO: Give error if we wanted a signed integer and we got an unsigned
one
*/
if (err > 0 ||
(end != org_end && !check_if_only_end_space(cs, end, org_end)))
if (!current_thd->no_errors &&
(err > 0 ||
(end != org_end && !check_if_only_end_space(cs, end, org_end))))
{
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE,
......
......@@ -4880,10 +4880,20 @@ bool Item_func_get_system_var::is_written_to_binlog()
}
void Item_func_get_system_var::update_null_value()
{
THD *thd= current_thd;
int save_no_errors= thd->no_errors;
thd->no_errors= TRUE;
Item::update_null_value();
thd->no_errors= save_no_errors;
}
void Item_func_get_system_var::fix_length_and_dec()
{
char *cptr;
maybe_null=0;
maybe_null= TRUE;
max_length= 0;
if (var->check_type(var_type))
......
......@@ -1455,6 +1455,7 @@ class Item_func_get_system_var :public Item_func
LEX_STRING *component_arg, const char *name_arg,
size_t name_len_arg);
enum Functype functype() const { return GSYSVAR_FUNC; }
void update_null_value();
void fix_length_and_dec();
void print(String *str, enum_query_type query_type);
bool const_item() const { return true; }
......
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