1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00
Files
mariadb/sql
Arcadiy Ivanov a4bb5c7b2e MDEV-21879 GROUP_CONCAT(DISTINCT ORDER BY) is wrong when Unique spills
`Item_func_group_concat::add()` decided whether a row was a duplicate
by checking whether `Unique::elements_in_tree()` had grown after
`unique_add()`:

    uint count= unique_filter->elements_in_tree();
    unique_filter->unique_add(get_record_pointer());
    if (count == unique_filter->elements_in_tree())
      row_eligible= FALSE;

`Unique` flushes its whole in-memory tree to disk when it runs out of
memory, and `elements_in_tree()` only counts what is still in memory.
After the first flush the test says nothing about the rows that were
already spilled.

**MDEV-11563** made this harmless for `GROUP_CONCAT(DISTINCT x)` by
building the result in `val_str()` from `unique_filter->walk()`, which
merges the spilled parts back in. It left the `ORDER BY` case alone.
There the result comes from the sort tree, which `add()` fills gated by
`row_eligible`, so the defect is still fully live.

Both directions of the failure are reachable, depending on how often
the filter flushes relative to the insert:

1. Duplicates reach the result. 100 rows holding 50 distinct values
   give all 100 values back.
2. Rows are lost. 30 distinct rows of 2000 bytes give one value back.

`JSON_ARRAYAGG(DISTINCT x ORDER BY y)` fails in the same way.

Fixed by not filling the sort tree from `add()` when `DISTINCT` is
used. `val_str()` now walks the merged `unique_filter` into the sort
tree and then walks the sort tree, so the rows are sorted after the
duplicate filtering is complete instead of during it.

`Unique::walk()` merges everything it flushed, so the sort tree can be
handed more rows than fit in memory. `insert_to_order_tree()` repacks
it on the same memory budget `add()` used, and a walk that runs out of
memory sets `result_cut`, so the user gets a cut value warning rather
than a silently short result.

**Behaviour change.** `ORDER BY` does not order rows that tie on the
ordering expression, and which of them comes first changes here. It
used to follow the order the rows were read in; it now follows the
order the duplicate filter keeps them in. Unlike the old order, the new
one depends on neither the memory available nor the physical row order.
`main.gconcat_distinct_spill` checks that, and `main.func_gconcat`
records one such tie.
2026-10-11 18:42:17 +03:00
..
2026-06-15 16:53:03 +02:00
…
2026-09-04 12:21:02 +02:00
2025-07-28 21:29:29 +02:00
2024-11-05 14:00:48 -08:00
2025-09-29 18:25:09 +03:00
…
2025-03-14 12:08:56 +04:00
2026-02-16 21:55:18 +01:00
2025-03-14 12:08:56 +04:00
…
2024-12-02 17:51:17 +02:00
2026-01-31 14:08:54 +01:00
2026-07-20 13:23:00 +03:00
2026-07-20 13:23:00 +03:00
…
2026-01-31 14:08:54 +01:00
2024-12-02 11:35:34 +02:00
2026-03-24 09:49:17 +02:00
2026-03-24 09:49:17 +02:00
…
…
2026-06-15 16:53:03 +02:00
2026-05-26 21:15:58 +02:00
2026-07-29 12:27:46 +02:00
2024-11-29 13:43:17 +02:00
…
…
2026-08-20 08:27:14 +02:00
2026-08-20 08:27:14 +02:00
2024-12-05 10:11:58 +01:00
2026-08-20 08:27:14 +02:00
2026-02-03 14:53:15 +01:00
2026-05-26 21:15:58 +02:00
2026-02-03 14:53:15 +01:00
2026-09-04 12:21:02 +02:00
2026-08-20 08:27:14 +02:00
2026-03-24 09:49:17 +02:00
2026-01-31 14:08:54 +01:00
2026-01-08 12:02:45 +01:00
2026-08-03 13:42:39 +02:00
2024-07-08 22:40:16 +02:00
2026-05-26 21:15:58 +02:00
2026-05-26 21:15:58 +02:00
…
2025-03-14 12:08:56 +04:00
2026-09-04 12:21:02 +02:00
…
2024-10-03 15:59:20 +10:00
…
2025-03-14 12:08:56 +04:00
2026-05-26 21:15:58 +02:00
2026-09-04 12:14:15 +02:00
2026-07-29 12:27:46 +02:00
2026-09-04 12:21:02 +02:00
2026-07-30 11:41:55 +02:00
2026-05-08 08:00:01 +02:00
2026-09-04 12:21:02 +02:00
2026-01-31 14:08:54 +01:00
2026-05-26 21:15:58 +02:00
2026-09-04 12:14:15 +02:00
2026-02-03 14:53:15 +01:00
2025-09-29 18:25:09 +03:00
2024-07-22 15:14:50 +02:00
2026-05-26 21:15:58 +02:00
2026-05-26 21:15:58 +02:00
2026-06-16 12:24:32 +02:00
2026-07-30 11:41:55 +02:00
2026-06-16 12:24:32 +02:00
2026-08-20 08:27:14 +02:00
2026-06-15 16:53:03 +02:00
2026-06-15 16:53:03 +02:00
2025-03-14 12:08:56 +04:00
2026-04-02 09:15:17 +03:00
2026-09-04 12:14:15 +02:00
2026-09-04 12:21:02 +02:00
2026-09-04 12:21:02 +02:00
2026-02-06 17:46:50 +01:00
2025-11-04 12:39:27 +01:00
2026-09-04 12:14:15 +02:00
2026-09-04 12:14:15 +02:00
2026-09-10 09:07:23 +03:00
2026-09-04 12:14:15 +02:00
2026-09-04 12:14:15 +02:00
2026-08-20 08:27:14 +02:00
2025-09-04 18:08:39 +03:00
2024-06-24 13:09:47 +03:00
2026-08-03 13:42:39 +02:00
2026-07-30 11:41:55 +02:00
2026-06-15 15:15:10 +02:00
2026-06-15 15:15:10 +02:00
2026-04-02 09:15:17 +03:00
2026-01-31 14:08:54 +01:00
2026-01-05 20:34:44 +01:00
2026-07-30 11:41:55 +02:00
2026-03-24 09:49:17 +02:00
2026-06-29 07:40:04 +03:00
2026-01-08 12:02:45 +01:00
2026-07-30 16:15:40 +02:00
2026-07-30 16:15:40 +02:00
2026-02-06 17:46:51 +01:00
2026-03-17 18:57:42 +01:00
2026-07-30 16:15:40 +02:00
…
2026-02-06 17:46:51 +01:00
2024-06-27 10:26:09 +03:00
2025-08-04 12:05:53 +02:00
2024-12-02 17:51:17 +02:00
2025-09-19 12:31:14 +03:00
2026-05-26 21:15:58 +02:00
2025-03-14 12:08:56 +04:00
2026-09-10 09:07:23 +03:00
2026-09-04 12:21:02 +02:00
2024-07-03 12:45:30 +02:00
2026-09-04 12:21:02 +02:00
2026-09-04 12:21:02 +02:00
2025-01-09 09:41:38 +02:00
2024-12-02 17:51:17 +02:00
2026-09-04 12:21:02 +02:00
2026-09-04 12:21:02 +02:00
2026-08-20 08:27:14 +02:00
2026-09-04 12:21:02 +02:00
2026-08-19 08:40:05 +02:00
2026-07-28 13:14:38 +02:00
2026-05-26 21:15:58 +02:00
…
2026-09-04 12:14:15 +02:00
2025-03-14 12:08:56 +04:00
2024-12-02 17:51:17 +02:00
2026-08-20 08:27:14 +02:00
2026-09-04 12:21:02 +02:00
2026-08-20 08:27:14 +02:00
2026-08-20 08:27:14 +02:00
2026-07-20 13:23:00 +03:00
2026-03-24 09:49:17 +02:00
2025-09-04 18:08:39 +03:00
2024-06-24 13:09:47 +03:00
2025-03-14 12:08:56 +04:00
2026-05-22 09:52:05 +02:00
2024-12-02 17:51:17 +02:00
2024-12-02 11:35:34 +02:00
2026-09-04 12:14:15 +02:00
2026-09-04 12:21:02 +02:00
2025-03-14 12:08:56 +04:00
2026-06-16 12:24:32 +02:00
2025-11-28 12:56:27 +02:00
2024-06-27 10:26:09 +03:00
2026-09-04 12:21:02 +02:00
2026-06-21 15:32:20 +02:00
2026-08-19 08:40:05 +02:00
2026-06-15 16:53:03 +02:00
2026-04-02 09:15:17 +03:00
2024-10-03 13:24:43 +03:00
2024-09-09 13:50:38 +03:00
2026-09-04 12:21:02 +02:00
2026-02-07 22:12:32 +01:00
2026-08-03 13:42:39 +02:00
2026-07-29 12:27:46 +02:00