Details
-
Bug
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
10.11, 11.4, 11.8, 12.3, 13.0, 13.1, 13.2
Description
Likely cause: old code, not a recent change. The hash for KEY partitioning is made from the stored bytes of a FLOAT, and -0 and 0 have different bytes. MySQL 5.5 to 9.1 give the same result.
--source include/have_partition.inc
|
CREATE TABLE t1 (c FLOAT) PARTITION BY KEY (c) PARTITIONS 7; |
INSERT INTO t1 VALUES (0), (-1e-50); |
--let $n= `SELECT COUNT(*) FROM t1 WHERE c = 0`
|
if ($n != 2) |
{
|
--die KEY partitioning puts the FLOAT values -0 and 0 in different partitions, and WHERE c = 0 finds $n of the 2 rows |
}
|
DROP TABLE t1; |
Leads to:
|
CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Optimized, Clang 22.1.8-20260622) Build 05/10/2026 |
mysqltest: At line 7: KEY partitioning puts the FLOAT values -0 and 0 in different partitions, and WHERE c = 0 finds 1 of the 2 rows
|
Partitioning changes the query result. Without partitioning, the query finds both rows. INSERT INTO t1 VALUES (-1e-50) stores -0, and DELETE FROM t1 WHERE c = 0 leaves the -0 row. KEY ALGORITHM=XXH32, ALGORITHM=1 and debug builds give the same result. A UNIQUE (c) USING HASH column accepts -0 next to 0 for the same reason.
From the code it seems that the hash uses the stored bytes of a FLOAT or DOUBLE value, in Field_num::hash_not_null(), and in mysql51_hash() for ALGORITHM=1. Field_float::store(double) changes -0.0 to 0.0 before the cast to FLOAT, so -1e-50 still becomes -0 in the cast.
Attachments
Issue Links
- relates to
-
MDEV-38670 Minus string is converted to -0
-
- Closed
-
-
MDEV-39350 Float value -0 gets replicated as 0 and hashes dont match
-
- Closed
-
-
MDEV-41478 PARTITION BY KEY and UNIQUE USING HASH treat equal CHAR values in a NO PAD collation as different: duplicate keys and missing rows
-
- Open
-