diff --git a/mysql-test/suite/sys_vars/r/innodb_thread_sleep_delay_basic.result b/mysql-test/suite/sys_vars/r/innodb_thread_sleep_delay_basic.result
index 0335db8..ebb9955 100644
--- a/mysql-test/suite/sys_vars/r/innodb_thread_sleep_delay_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_thread_sleep_delay_basic.result
@@ -42,7 +42,9 @@ ERROR 42000: Incorrect argument type to variable 'innodb_thread_sleep_delay'
 set global innodb_thread_sleep_delay="foo";
 ERROR 42000: Incorrect argument type to variable 'innodb_thread_sleep_delay'
 set global innodb_thread_sleep_delay=18446744073709551616;
-ERROR 42000: Incorrect argument type to variable 'innodb_thread_sleep_delay'
+Warnings:
+Warning	1916	Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Warning	1292	Truncated incorrect innodb_thread_sleep_delay value: '9223372036854775807'
 set global innodb_thread_sleep_delay=-7;
 Warnings:
 Warning	1292	Truncated incorrect innodb_thread_sleep_delay value: '-7'
diff --git a/mysql-test/suite/sys_vars/r/wait_timeout_basic.result b/mysql-test/suite/sys_vars/r/wait_timeout_basic.result
index 6dc99dc..d0e5188 100644
--- a/mysql-test/suite/sys_vars/r/wait_timeout_basic.result
+++ b/mysql-test/suite/sys_vars/r/wait_timeout_basic.result
@@ -124,5 +124,17 @@ SELECT session.wait_timeout;
 ERROR 42S02: Unknown table 'session' in field list
 SELECT wait_timeout = @@session.wait_timeout;
 ERROR 42S22: Unknown column 'wait_timeout' in 'field list'
+#
+# MDEV-9516 type error when setting session variable
+#
+SET SESSION wait_timeout= 28000;
+SET SESSION wait_timeout= GREATEST(28000, @@wait_timeout);
+SET SESSION wait_timeout= COALESCE(28000, @@wait_timeout);
+SET SESSION wait_timeout= IFNULL(28000, @@wait_timeout);
+SET SESSION wait_timeout= CASE WHEN TRUE THEN 28000 ELSE @@wait_timeout END;
+SET SESSION wait_timeout= 28000.0;
+ERROR 42000: Incorrect argument type to variable 'wait_timeout'
+SET SESSION wait_timeout= 28000.1;
+ERROR 42000: Incorrect argument type to variable 'wait_timeout'
 SET @@global.wait_timeout = @start_global_value;
 SET @@session.wait_timeout = @start_session_value;
diff --git a/mysql-test/suite/sys_vars/t/innodb_thread_sleep_delay_basic.test b/mysql-test/suite/sys_vars/t/innodb_thread_sleep_delay_basic.test
index 85ae235..bc4efdd 100644
--- a/mysql-test/suite/sys_vars/t/innodb_thread_sleep_delay_basic.test
+++ b/mysql-test/suite/sys_vars/t/innodb_thread_sleep_delay_basic.test
@@ -39,7 +39,7 @@ set global innodb_thread_sleep_delay=1.1;
 set global innodb_thread_sleep_delay=1e1;
 --error ER_WRONG_TYPE_FOR_VAR
 set global innodb_thread_sleep_delay="foo";
---error ER_WRONG_TYPE_FOR_VAR
+
 set global innodb_thread_sleep_delay=18446744073709551616;
 
 set global innodb_thread_sleep_delay=-7;
diff --git a/mysql-test/suite/sys_vars/t/wait_timeout_basic.test b/mysql-test/suite/sys_vars/t/wait_timeout_basic.test
index e92a329..598f6cb 100644
--- a/mysql-test/suite/sys_vars/t/wait_timeout_basic.test
+++ b/mysql-test/suite/sys_vars/t/wait_timeout_basic.test
@@ -203,6 +203,20 @@ SELECT session.wait_timeout;
 --Error ER_BAD_FIELD_ERROR
 SELECT wait_timeout = @@session.wait_timeout;
 
+--echo #
+--echo # MDEV-9516 type error when setting session variable
+--echo #
+
+SET SESSION wait_timeout= 28000;
+SET SESSION wait_timeout= GREATEST(28000, @@wait_timeout);
+SET SESSION wait_timeout= COALESCE(28000, @@wait_timeout);
+SET SESSION wait_timeout= IFNULL(28000, @@wait_timeout);
+SET SESSION wait_timeout= CASE WHEN TRUE THEN 28000 ELSE @@wait_timeout END;
+
+--error ER_WRONG_TYPE_FOR_VAR
+SET SESSION wait_timeout= 28000.0;
+--error ER_WRONG_TYPE_FOR_VAR
+SET SESSION wait_timeout= 28000.1;
 
 ####################################
 #     Restore initial value        #
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 18f6cbc..b5430c5 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -739,7 +739,7 @@ int set_var::check(THD *thd)
   if ((!value->fixed &&
        value->fix_fields(thd, &value)) || value->check_cols(1))
     return -1;
-  if (var->check_update_type(value->result_type()))
+  if (var->check_update_type(value))
   {
     my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name.str);
     return -1;
diff --git a/sql/set_var.h b/sql/set_var.h
index b8192e6..cf86ecf 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -137,8 +137,9 @@ class sys_var: protected Value_source // for double_from_string_with_check
   bool is_set_stmt_ok() const { return !(flags & NO_SET_STATEMENT); }
   bool is_written_to_binlog(enum_var_type type)
   { return type != OPT_GLOBAL && binlog_status == SESSION_VARIABLE_IN_BINLOG; }
-  bool check_update_type(Item_result type)
+  bool check_update_type(const Item *item)
   {
+    Item_result type= item->result_type();
     switch (option.var_type & GET_TYPE_MASK) {
     case GET_INT:
     case GET_UINT:
@@ -146,7 +147,8 @@ class sys_var: protected Value_source // for double_from_string_with_check
     case GET_ULONG:
     case GET_LL:
     case GET_ULL:
-      return type != INT_RESULT;
+      return type != INT_RESULT &&
+             (type != DECIMAL_RESULT || item->decimals != 0);
     case GET_STR:
     case GET_STR_ALLOC:
       return type != STRING_RESULT;
