mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
MDEV-35592 Duplicate entry 'NULL' for key 'key0' with subquery cache
Expression cache lookup is null rejecting, so parameters with NULL never hit and were inserted into the cache table again and again. After conversion of the cache to an on-disk table (where NULLs are equal) such a repeated insert failed with ER_DUP_ENTRY. Do not store rows which can not be looked up. On 11.4 the cache is just switched off when the HEAP table is full, so the test fails only after MDEV-9101 (11.5+, ES 11.4 via MENT-2067). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3960,5 +3960,25 @@ Note 1981 Aggregate function 'bit_or()' of SELECT #4 belongs to SELECT #3
|
||||
Note 1276 Field or reference 'd' of SELECT #3 was resolved in SELECT #1
|
||||
Note 1003 /* select#1 */ select `test`.`t1`.`c` AS `d` from `test`.`t1` join `test`.`t1` where <expr_cache><`test`.`t1`.`c`>((/* select#3 */ select ord(<expr_cache><`test`.`t1`.`c`,bit_or(`test`.`t1`.`c`),bit_or(`test`.`t1`.`c`)>((/* select#4 */ select bit_or(`test`.`t1`.`c`)))) from `test`.`t1` group by `test`.`t1`.`c`))
|
||||
DROP TABLE t0, t1;
|
||||
#
|
||||
# MDEV-35592 ERROR 1062 (23000): Duplicate entry 'NULL' for key 'key0'
|
||||
# on CONCAT in sub-query
|
||||
#
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1
|
||||
WITH RECURSIVE s(n) AS (SELECT 0 UNION ALL SELECT n + 1 FROM s WHERE n < 999)
|
||||
SELECT n FROM s, (VALUES (1), (2), (3), (4)) AS x ORDER BY n;
|
||||
INSERT INTO t1 VALUES (NULL), (NULL);
|
||||
CREATE TABLE t2 (b INT);
|
||||
INSERT INTO t2 VALUES (1), (2);
|
||||
SET @save_tmp_table_size= @@tmp_table_size;
|
||||
SET @save_max_heap_table_size= @@max_heap_table_size;
|
||||
SET tmp_table_size= 16384, max_heap_table_size= 16384;
|
||||
SELECT COUNT(*) FROM t1 WHERE (SELECT b FROM t2 WHERE t2.b = t1.a) IS NULL;
|
||||
COUNT(*)
|
||||
3994
|
||||
SET tmp_table_size= @save_tmp_table_size;
|
||||
SET max_heap_table_size= @save_max_heap_table_size;
|
||||
DROP TABLE t1, t2;
|
||||
# End of 11.4 tests
|
||||
SET optimizer_switch=@save_optimizer_switch;
|
||||
|
||||
@@ -1769,6 +1769,29 @@ EXPLAIN EXTENDED SELECT t2.d FROM (SELECT c AS d FROM t1) AS t2 JOIN t1 ON (
|
||||
|
||||
DROP TABLE t0, t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-35592 ERROR 1062 (23000): Duplicate entry 'NULL' for key 'key0'
|
||||
--echo # on CONCAT in sub-query
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1
|
||||
WITH RECURSIVE s(n) AS (SELECT 0 UNION ALL SELECT n + 1 FROM s WHERE n < 999)
|
||||
SELECT n FROM s, (VALUES (1), (2), (3), (4)) AS x ORDER BY n;
|
||||
INSERT INTO t1 VALUES (NULL), (NULL);
|
||||
CREATE TABLE t2 (b INT);
|
||||
INSERT INTO t2 VALUES (1), (2);
|
||||
|
||||
SET @save_tmp_table_size= @@tmp_table_size;
|
||||
SET @save_max_heap_table_size= @@max_heap_table_size;
|
||||
SET tmp_table_size= 16384, max_heap_table_size= 16384;
|
||||
|
||||
SELECT COUNT(*) FROM t1 WHERE (SELECT b FROM t2 WHERE t2.b = t1.a) IS NULL;
|
||||
|
||||
SET tmp_table_size= @save_tmp_table_size;
|
||||
SET max_heap_table_size= @save_max_heap_table_size;
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--echo # End of 11.4 tests
|
||||
|
||||
SET optimizer_switch=@save_optimizer_switch;
|
||||
|
||||
@@ -271,6 +271,18 @@ my_bool Expression_cache_tmptable::put_value(Item *value)
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
check_value() could not build the lookup key (e.g. NULL in the null
|
||||
rejecting key part), so such a row would never be found. Do not store
|
||||
it: duplicates of it are rejected after conversion to an on-disk table,
|
||||
where NULLs are equal.
|
||||
*/
|
||||
if (ref.key_err)
|
||||
{
|
||||
DBUG_PRINT("info", ("Key can not be looked up, do not store it"));
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
*(items.head_ref())= value;
|
||||
fill_record(table_thd, cache_table, cache_table->field, items, true, true,
|
||||
true);
|
||||
|
||||
Reference in New Issue
Block a user