Commit 24abbb9b authored by Alexander Barkov's avatar Alexander Barkov

MDEV-21034 GREATEST() and LEAST() malfunction for NULL

There is a convention that Item::val_int() and Item::val_real() return
SQL NULL doing effectively what this code does:
  null_value= true;
  return 0; // Always return 0 for SQL NULL

This is done to optimize boolean value evaluation:
if Item::val_int() or Item::val_real() returned 1 -
that always means TRUE and never can means SQL NULL.
This convention helps to avoid unnecessary testing
Item::null_value after getting a non-zero return value.

Item_func_min_max did not follow this convention.
It could return a non-zero value together with null_value==true.
This made evaluate_join_record() erroneously misinterpret
SQL NULL as TRUE in this call:

  select_cond_result= MY_TEST(select_cond->val_int());

Fixing Item_func_min_max to follow the convention.
parent 361b7903
......@@ -4313,5 +4313,30 @@ ERROR HY000: Illegal parameter data types bigint unsigned and row for operation
SELECT @@max_allowed_packet=ROW(1,1);
ERROR HY000: Illegal parameter data types bigint unsigned and row for operation '='
#
# MDEV-21034 GREATEST() and LEAST() malfunction for NULL
#
SELECT 5 AS c1 FROM dual WHERE GREATEST(1, NULL);
c1
SELECT 5 AS c1 FROM dual WHERE LEAST(1, NULL);
c1
CREATE TABLE t0 (c0 INT);
INSERT INTO t0 VALUES (1);
SELECT * FROM t0 WHERE GREATEST(c0, NULL);
c0
SELECT * FROM t0 WHERE LEAST(c0, NULL);
c0
DROP TABLE t0;
SELECT 5 AS c1 FROM dual WHERE GREATEST(1e0, NULL);
c1
SELECT 5 AS c1 FROM dual WHERE LEAST(1e0, NULL);
c1
CREATE TABLE t0 (c0 DOUBLE);
INSERT INTO t0 VALUES (1);
SELECT * FROM t0 WHERE GREATEST(c0, NULL);
c0
SELECT * FROM t0 WHERE LEAST(c0, NULL);
c0
DROP TABLE t0;
#
# End of 10.5 tests
#
......@@ -1115,6 +1115,29 @@ SELECT 0x20+ROW(1,1);
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT @@max_allowed_packet=ROW(1,1);
--echo #
--echo # MDEV-21034 GREATEST() and LEAST() malfunction for NULL
--echo #
SELECT 5 AS c1 FROM dual WHERE GREATEST(1, NULL);
SELECT 5 AS c1 FROM dual WHERE LEAST(1, NULL);
CREATE TABLE t0 (c0 INT);
INSERT INTO t0 VALUES (1);
SELECT * FROM t0 WHERE GREATEST(c0, NULL);
SELECT * FROM t0 WHERE LEAST(c0, NULL);
DROP TABLE t0;
SELECT 5 AS c1 FROM dual WHERE GREATEST(1e0, NULL);
SELECT 5 AS c1 FROM dual WHERE LEAST(1e0, NULL);
CREATE TABLE t0 (c0 DOUBLE);
INSERT INTO t0 VALUES (1);
SELECT * FROM t0 WHERE GREATEST(c0, NULL);
SELECT * FROM t0 WHERE LEAST(c0, NULL);
DROP TABLE t0;
--echo #
--echo # End of 10.5 tests
--echo #
......@@ -3022,7 +3022,7 @@ double Item_func_min_max::val_real_native()
value=tmp;
}
if ((null_value= args[i]->null_value))
break;
return 0;
}
return value;
}
......@@ -3043,7 +3043,7 @@ longlong Item_func_min_max::val_int_native()
value=tmp;
}
if ((null_value= args[i]->null_value))
break;
return 0;
}
return value;
}
......
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