summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/func_misc.result9
-rw-r--r--mysql-test/t/func_misc.test6
-rw-r--r--sql/item_func.cc19
-rw-r--r--sql/item_func.h11
4 files changed, 32 insertions, 13 deletions
diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result
index 8d89b63d861..a19676168c2 100644
--- a/mysql-test/r/func_misc.result
+++ b/mysql-test/r/func_misc.result
@@ -1557,5 +1557,14 @@ numgtfmt
DROP VIEW v1;
DROP TABLE t1;
#
+# MDEV-20517 Assertion `!is_expensive()' failed in Item::value_depends_on_sql_mode_const_item
+#
+SELECT ( 1 LIKE GET_LOCK( 'foo', 0 ) ) - 2;
+( 1 LIKE GET_LOCK( 'foo', 0 ) ) - 2
+-1
+SELECT RELEASE_LOCK('foo');
+RELEASE_LOCK('foo')
+1
+#
# End of 10.2 tests
#
diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test
index 89c1744c354..cdbbe708153 100644
--- a/mysql-test/t/func_misc.test
+++ b/mysql-test/t/func_misc.test
@@ -1192,6 +1192,12 @@ SELECT * FROM v1 WHERE numgtfmt = NAME_CONST('wnumgtfmt',_utf8'QEDITIONS' COLLA
DROP VIEW v1;
DROP TABLE t1;
+--echo #
+--echo # MDEV-20517 Assertion `!is_expensive()' failed in Item::value_depends_on_sql_mode_const_item
+--echo #
+
+SELECT ( 1 LIKE GET_LOCK( 'foo', 0 ) ) - 2;
+SELECT RELEASE_LOCK('foo');
--echo #
--echo # End of 10.2 tests
diff --git a/sql/item_func.cc b/sql/item_func.cc
index d11b56f2aad..5deeccc9265 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1423,17 +1423,22 @@ bool Item_func_minus::fix_length_and_dec()
{
if (Item_num_op::fix_length_and_dec())
return TRUE;
- m_sql_mode_dependency= Item_func::value_depends_on_sql_mode();
- if (unsigned_flag)
- {
- m_sql_mode_dependency|= Sql_mode_dependency(0,MODE_NO_UNSIGNED_SUBTRACTION);
- if (current_thd->variables.sql_mode & MODE_NO_UNSIGNED_SUBTRACTION)
- unsigned_flag= false;
- }
+ if ((m_depends_on_sql_mode_no_unsigned_subtraction= unsigned_flag) &&
+ (current_thd->variables.sql_mode & MODE_NO_UNSIGNED_SUBTRACTION))
+ unsigned_flag= false;
return FALSE;
}
+Sql_mode_dependency Item_func_minus::value_depends_on_sql_mode() const
+{
+ Sql_mode_dependency dep= Item_func_additive_op::value_depends_on_sql_mode();
+ if (m_depends_on_sql_mode_no_unsigned_subtraction)
+ dep|= Sql_mode_dependency(0, MODE_NO_UNSIGNED_SUBTRACTION);
+ return dep;
+}
+
+
double Item_func_minus::real_op()
{
double value= args[0]->val_real() - args[1]->val_real();
diff --git a/sql/item_func.h b/sql/item_func.h
index 5be62427852..1193daea106 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -773,16 +773,15 @@ public:
class Item_func_minus :public Item_func_additive_op
{
- Sql_mode_dependency m_sql_mode_dependency;
+ bool m_depends_on_sql_mode_no_unsigned_subtraction;
public:
Item_func_minus(THD *thd, Item *a, Item *b):
- Item_func_additive_op(thd, a, b) {}
+ Item_func_additive_op(thd, a, b),
+ m_depends_on_sql_mode_no_unsigned_subtraction(false)
+ { }
const char *func_name() const { return "-"; }
enum precedence precedence() const { return ADD_PRECEDENCE; }
- Sql_mode_dependency value_depends_on_sql_mode() const
- {
- return m_sql_mode_dependency;
- }
+ Sql_mode_dependency value_depends_on_sql_mode() const;
longlong int_op();
double real_op();
my_decimal *decimal_op(my_decimal *);