Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Duplicate
-
12.3.2
-
None
-
Operating system:
- Ubuntu 20.04.6 LTS (Focal Fossa)
- Linux kernel: 5.4.0-204-generic
- Architecture: x86_64
Hardware:
- CPU: 2 × Intel Xeon Gold 5218R @ 2.10 GHz
- 40 physical cores / 80 logical CPUs
-
Not for Release Notes
Description
-
-
- Problem Description
With `sql_buffer_result = OFF`, a single-table query (Q1) and a query after rebuilding via a two-table JOIN into a temporary table (Q2) return different results for the same expression `CONCAT(CAST(-j AS CHAR), 'a')`. Q1 returns `'0a'`, while Q2 returns `'0'`, losing the trailing character `'a'`.
- Problem Description
-
In Q1, `src.id` is the primary key, so each `id` has only one row. Thus the `DISTINCT` in `DISTINCT id, v` is effectively redundant. The MariaDB optimizer can simply drop `DISTINCT`, avoid creating an internal dedup temporary table, and directly compute the expression and output it, producing the correct `'0a'`.
In Q2, `rebuilt.id` is not the primary key (`rebuilt.rid` is), so `DISTINCT id, v` cannot be simply dropped. MariaDB needs to create an internal temporary table for deduplication. It is suspected that when writing to the dedup temp table, for expressions like `CONCAT(CAST(-j AS CHAR), 'a')` that do not explicitly specify a `CAST` length, the result column length is misdeduced, causing `'0a'` to be truncated to `'0'`.
-
-
- How to Reproduce
Execute the following SQL:
- How to Reproduce
-
```sql
DROP DATABASE IF EXISTS repro_mariadb815_db10_min;
CREATE DATABASE repro_mariadb815_db10_min;
USE repro_mariadb815_db10_min;
SET SESSION sql_buffer_result = OFF;
CREATE TABLE src (
rid INT,
id INT PRIMARY KEY,
j LONGTEXT
) ENGINE=InnoDB;
INSERT INTO src VALUES (1, 1, '{}');
CREATE TABLE l (
rid INT PRIMARY KEY,
id INT
) ENGINE=InnoDB;
CREATE TABLE r (
rid INT PRIMARY KEY,
j LONGTEXT
) ENGINE=InnoDB;
INSERT INTO l SELECT rid, id FROM src;
INSERT INTO r SELECT rid, j FROM src;
DROP TEMPORARY TABLE IF EXISTS rebuilt;
CREATE TEMPORARY TABLE rebuilt (
rid INT PRIMARY KEY,
id INT,
j LONGTEXT
) ENGINE=InnoDB;
INSERT INTO rebuilt
SELECT l.rid, l.id, r.j
FROM l JOIN r USING (rid);
– Q1: single-table query
SELECT DISTINCT id, CONCAT(CAST(-j AS CHAR), 'a') AS v
FROM src;
– Q2: query after rebuilding into a temporary table via two-table JOIN
SELECT DISTINCT id, CONCAT(CAST(-j AS CHAR), 'a') AS v
FROM rebuilt;
```
-
-
- Expected Behavior
Q1 and Q2 should return the same result, i.e., both should return:
```
--------+id v ---
-----+1 0a ---
-----+
```
- Expected Behavior
-
-
-
- Actual Behavior
-
- Q1: returns `'0a'`.
- Q2: returns `'0'`, with the trailing character `'a'` truncated.
Q1 result:
```
--------+
| id | v |
--------+
| 1 | 0a |
--------+
```
Q2 result:
```
----------+
| id | v |
----------+
| 1 | 0 |
----------+
```
Attachments
Issue Links
- duplicates
-
MDEV-38210 Unary negation of LONGTEXT, wrong result under GROUP BY
-
- Closed
-