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

MDEV-37057 Wrong result with LATERAL DERIVED

When populating the structure spl_opt_info for a TABLE, and evaluating a
key_field for inclusion in spl_opt_info->added_key_fields, the null_rejecting
attribute may be incorrectly set.  Originally, this attribute was
assumed to be TRUE, then it was changed

  Item *real= key_field->val->real_item();
  if ((real->type() == Item::FIELD_ITEM) &&
        ((Item_field*)real)->field->maybe_null())
    added_key_field->null_rejecting= true;
  else
    added_key_field->null_rejecting= false;

which also incorrectly assumed that the added key field depended on
whether the field was able to set to null.

The correct setting for this attribute is simply to pass it through from
the key being evaluated.

The result of an incorrect value is, in this test case, incorrect
equality conditions being pushed into our (lateral) derived table,
excluding rows that might legitimately contain NULL and thus returning
a wrong result.

Approved by Sergei Petrunia, PR#4140
This commit is contained in:
Rex Johnston
2025-06-23 15:05:44 +11:00
committed by Rex Johnston
parent dbeef00562
commit aa3578aa8a
3 changed files with 79 additions and 8 deletions

View File

@@ -561,4 +561,47 @@ DROP TABLE t1;
--echo # End of 10.4 tests
--echo #
--echo # MDEV-37057 Wrong result with LATERAL DERIVED
--echo #
CREATE TABLE t1 (
a int NOT NULL,
b int default null,
amount decimal DEFAULT NULL,
KEY t1_IDX (a,b) USING BTREE
) ENGINE=INNODB;
CREATE TABLE t2 (
a int NOT NULL,
b int default null,
name varchar(50) DEFAULT NULL,
KEY t2_IDX (a,b) USING BTREE
) ENGINE=INNODB;
INSERT INTO t1 VALUES
(1, NULL, 10.0000), (2, 2, 20.0000), (3, 3, 30.0000), (4, 4, 40.0000),
(5, 5, NULL), (6, 6, NULL), (7, 7, 70.0000), (8, 8, 80.0000);
INSERT INTO t2 VALUES
(1, NULL, 'A'), (2,2, 'B'), (3,3, 'C'), (4,4, 'D'), (5,5, NULL), (6,6, NULL),
(7,7, 'E'), (8,8, 'F'), (9,9, 'G'), (10,10,'H'), (11,11, NULL), (12,12, NULL);
let $query=
SELECT t2.a,t2.b,t2.name,t.total_amt FROM t2
LEFT JOIN
(
SELECT a, b, sum(amount) total_amt FROM t1 GROUP BY a, b
) AS t ON t2.a=t.a and t2.b<=>t.b
WHERE t2.a < 2;
--echo # Must use Split-Materialized:
evalp explain $query;
evalp $query;
--echo # Compare with correct result:
evalp set statement optimizer_switch='split_materialized=off' for $query;
DROP TABLE t1,t2;
# End of 11.4 tests;
SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent;