1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00
Files
mariadb/sql
Rex Johnston 8e11a253d0 MDEV-35845 Let string constants enter multiple equalities for all collations
SELECT * FROM t1 WHERE v IN ('a','b') AND v = 'b' kept both conjuncts
when v is a utf8mb4 column, while the same query on a latin1 column was
simplified to v = 'b'.  BETWEEN and the constant in a join equality
(t1.v = t2.v AND t1.v = 'b') were left alone in the same way.

The rewrite is done by the multiple equality machinery, not by
propagate_cond_constants().  check_simple_equality() turns v = 'b' into
an Item_equal holding the column and the constant.  Later
substitute_for_best_equal_field() walks the remaining predicates, and
Item_func_in::propagate_equal_fields() asks each argument that is a
column of an Item_equal to replace itself with that constant whenever
the predicate compares under the Item_equal's collation.  'b' IN
('a','b') is then constant and remove_eq_conds() folds it away.  The
same path serves BETWEEN, <=> and every other comparison, and
eliminate_item_equal() derives t2.v = 'b' from the join equality.

A constant was only admitted into an Item_equal when the column's
collation handler reported propagate() true.  That flag was added in
2005 for Bug#9509, when a constant taken from an Item_equal was
substituted into any expression, so LENGTH(s1) saw 'oe' instead of the
o-umlaut it equals under latin1_german2_ci.  Every utf8mb3 and utf8mb4
case-insensitive collation and every UCA collation report false, so
once MDEV-19123 made utf8mb4 the default, no string column got a
constant in its Item_equal.  Since MDEV-7152 the substitution is
decided per site by a Context: comparison operators accept the constant
only when their comparison collation is the Item_equal's, everything
else only for binary no-pad collations, and LIKE refuses pad and
non-1-to-1 collations on its own.  The flag therefore duplicated a
finer check, and propagate_cond_constants() had been substituting the
same constants into = and < under the same collations without
consulting it.  Field_str::test_if_equality_guarantees_uniqueness() no
longer consults it either; the remaining tests, that the constant
compares as a string and under the column's own collation, stay.

That exposes one case the flag was hiding.  Charset narrowing
(cset_narrowing) lets a utf8mb3_general_ci column and a
utf8mb4_general_ci column share an Item_equal, so the Item_equal now
also has to hold a utf8mb4 constant for its utf8mb3 member.
eliminate_item_equal() manufactures utf8mb3_col = utf8mb4_const for
that member, which fails collation aggregation when the constant has a
character outside the BMP.  Field_longstr::get_equal_const_item()
converts the constant from the Item_equal's comparison collation into
the member's character set, through the mb4-to-mb3 narrowing charset
when narrowing applies, so that a character outside the BMP becomes
U+FFFD, which is what utf8mb4_general_ci compares it as.  It returns
NULL, and the equality is dropped, when the constant cannot be
represented.  eliminate_item_equal() calls it for every member it
builds an equality for; Item_field::propagate_equal_fields() already
did.

The tests added to func_in.test come from Dave Gosselin's patch for
this issue, which handled IN in propagate_cond_constants() instead.
Two of its expectations change with this approach: an Item_equal prints
its constant first, and v IN ('a',NULL) AND v = 'b' now folds to an
impossible WHERE, as 'b' IN ('a',NULL) is NULL.  The other re-recorded
results show the same reordering, or improved plans where a constant
now reaches another table.  In main.ps and main.join a self-join of
INFORMATION_SCHEMA tables on TABLE_NAME now narrows both sides to the
named table, so the InnoDB tables in the data directory are no longer
opened and their "Unknown storage engine" warnings disappear.  In
spider/bugfix.mdev_27172 the CASE greeting WHEN 'Aloha!' ... = 'one'
conjunct, used there to keep the group by handler out, folds to TRUE
once greeting is substituted by its constant, so the condition Spider
pushes down to the remote is now just greeting = 'Aloha!'.

This commit was prepared with Claude Code (Fable 5.1), which traced the
missing rewrite to the propagate() check, showed by experiment that
removing it restores the rewrite and passes the func_in tests, found
the narrowing failure from a query supplied by the author, wrote
Field_longstr::get_equal_const_item() and its call in
eliminate_item_equal(), re-recorded the affected results, and ran the
main suite in normal and --ps-protocol mode before and after.
2026-10-15 14:42:54 +13:00
..
2026-05-08 08:11:03 +02:00
2025-10-25 00:19:11 +07:00
…
2026-08-19 11:28:01 +02:00
2024-11-10 19:22:21 +01:00
2025-07-28 21:29:29 +02:00
2024-11-05 14:00:48 -08:00
2026-07-29 12:27:46 +02:00
…
2025-09-29 18:25:09 +03:00
…
…
…
…
2024-12-02 11:35:34 +02:00
2024-12-02 17:51:17 +02:00
2026-01-31 14:08:54 +01:00
2024-10-30 15:11:17 +01:00
…
2024-12-02 11:35:34 +02:00
2026-04-20 13:16:55 +10:00
2026-03-23 11:57:44 +02:00
…
…
…
2024-11-08 07:17:00 +01:00
2026-04-20 13:16:55 +10:00
2026-06-15 15:15:10 +02:00
2025-09-04 18:08:39 +03:00
2026-08-19 11:28:01 +02:00
2026-07-29 12:27:46 +02:00
2024-11-29 13:43:17 +02:00
…
…
2026-08-19 11:28:01 +02:00
2026-08-19 11:28:01 +02:00
2024-12-05 10:11:58 +01:00
2026-08-19 11:28:01 +02:00
2026-07-29 12:27:46 +02:00
2026-08-19 11:28:01 +02:00
2026-01-31 14:08:54 +01:00
2026-08-19 11:28:01 +02:00
2026-05-08 08:11:03 +02:00
2026-08-19 11:28:01 +02:00
2026-07-29 12:27:46 +02:00
2026-08-19 11:28:01 +02:00
2026-07-29 12:27:46 +02:00
2026-01-31 14:08:54 +01:00
2026-06-26 13:46:45 +03:00
2026-01-31 14:08:54 +01:00
2026-01-31 14:08:54 +01:00
2026-04-01 15:03:59 +03:00
2026-01-28 14:22:20 +01:00
2024-12-02 11:35:34 +02:00
2026-07-29 12:27:46 +02:00
2024-12-02 17:51:17 +02:00
2024-11-05 14:00:50 -08:00
…
2026-08-19 11:28:01 +02:00
2026-08-19 11:28:01 +02:00
2026-08-19 11:28:01 +02:00
2026-05-08 08:11:03 +02:00
…
…
2025-09-29 18:25:09 +03:00
2026-04-01 15:03:59 +03:00
…
2024-10-03 15:59:20 +10:00
2024-12-02 11:35:34 +02:00
…
…
2026-08-19 11:28:01 +02:00
2026-08-19 11:28:01 +02:00
2026-07-29 12:27:46 +02:00
2026-08-19 11:28:01 +02:00
2026-01-31 14:08:54 +01:00
2026-01-31 14:08:54 +01:00
2025-09-29 18:25:09 +03:00
2026-08-19 11:28:01 +02:00
2026-07-28 13:14:38 +02:00
2024-12-02 11:35:34 +02:00
2026-07-28 13:14:38 +02:00
2026-05-08 08:00:01 +02:00
2026-08-19 11:28:01 +02:00
2026-01-31 14:08:54 +01:00
2026-05-08 08:11:03 +02:00
2025-09-29 18:25:09 +03:00
2025-09-29 18:25:09 +03:00
2024-07-22 15:14:50 +02:00
2026-05-08 08:11:03 +02:00
2026-05-08 08:00:01 +02:00
2026-05-08 08:11:03 +02:00
2026-06-15 15:15:10 +02:00
2026-07-29 12:27:46 +02:00
2026-06-15 15:15:10 +02:00
2025-09-29 18:25:09 +03:00
2026-08-19 08:40:05 +02:00
2026-08-19 08:40:05 +02:00
2026-06-15 15:15:10 +02:00
2026-06-15 15:15:10 +02:00
2026-08-19 11:28:01 +02:00
2026-08-19 11:28:01 +02:00
2026-08-19 11:28:01 +02:00
2026-03-23 11:57:44 +02:00
2025-11-04 12:39:27 +01:00
2025-11-04 12:39:27 +01:00
2026-08-19 11:28:01 +02:00
2026-07-29 12:27:46 +02:00
2026-05-08 08:11:03 +02:00
2026-07-29 12:27:46 +02:00
2026-07-29 12:27:46 +02:00
2026-07-29 12:27:46 +02:00
2026-07-29 12:27:46 +02:00
2026-07-29 12:27:46 +02:00
2024-12-02 17:51:17 +02:00
2026-08-19 11:28:01 +02:00
2026-01-05 20:34:44 +01:00
2025-09-04 18:08:39 +03:00
2026-08-19 11:28:01 +02:00
2025-02-06 16:46:36 +01:00
2026-04-20 13:16:55 +10:00
2026-07-29 12:27:46 +02:00
2026-07-29 12:27:46 +02:00
2026-06-15 15:15:10 +02:00
2026-06-15 15:15:10 +02:00
2024-11-29 13:43:17 +02:00
2026-08-19 11:28:01 +02:00
2026-05-08 08:11:03 +02:00
2025-09-29 18:25:09 +03:00
2026-04-01 15:03:59 +03:00
2024-12-02 17:51:17 +02:00
2026-08-19 11:28:01 +02:00
2026-01-31 14:08:54 +01:00
2026-01-05 20:34:44 +01:00
2026-07-29 12:27:46 +02:00
2024-10-03 13:24:43 +03:00
2026-03-23 11:57:44 +02:00
2026-06-26 13:46:45 +03:00
2026-01-05 20:34:44 +01:00
2026-07-29 12:27:46 +02:00
2026-07-29 12:27:46 +02:00
2026-07-29 12:27:46 +02:00
2025-03-03 11:07:56 +02:00
2026-03-17 18:57:42 +01:00
2026-08-19 11:28:01 +02:00
…
2026-04-01 15:03:59 +03:00
2025-09-29 18:25:09 +03:00
2025-09-29 18:25:09 +03:00
2025-01-09 09:41:38 +02:00
2024-10-30 15:11:17 +01:00
2024-12-02 17:51:17 +02:00
2026-07-29 12:27:46 +02:00
2025-09-19 12:31:14 +03:00
2025-09-29 18:25:09 +03:00
2025-09-04 18:08:39 +03:00
2026-07-29 12:27:46 +02:00
2026-07-29 12:27:46 +02:00
2025-09-29 18:25:09 +03:00
2026-05-08 08:11:03 +02:00
2026-08-19 11:28:01 +02:00
2026-01-31 14:08:54 +01:00
2026-08-19 11:28:01 +02:00
2025-01-09 09:41:38 +02:00
2026-07-29 12:27:46 +02:00
2024-11-05 14:00:47 -08:00
2024-12-02 17:51:17 +02:00
2026-08-19 11:28:01 +02:00
2026-07-29 12:27:46 +02:00
2026-08-19 11:28:01 +02:00
2026-06-15 15:15:10 +02:00
2026-04-20 13:16:55 +10:00
2025-09-29 18:25:09 +03:00
2026-08-19 11:28:01 +02:00
2026-03-23 11:57:44 +02:00
2026-07-29 12:27:46 +02:00
2026-08-19 08:40:05 +02:00
2026-07-28 13:14:38 +02:00
2026-07-29 12:27:46 +02:00
2025-02-11 20:29:43 +01:00
2025-04-02 14:07:01 +03:00
2026-05-08 08:00:01 +02:00
…
2026-05-08 08:11:03 +02:00
2026-08-19 11:28:01 +02:00
2026-07-29 12:27:46 +02:00
2024-12-02 17:51:17 +02:00
2024-12-02 17:51:17 +02:00
2026-08-19 11:28:01 +02:00
2026-07-29 12:27:46 +02:00
2026-07-29 12:27:46 +02:00
2026-06-15 15:15:10 +02:00
2026-08-19 11:28:01 +02:00
2026-08-19 11:28:01 +02:00
2026-08-19 11:28:01 +02:00
2026-08-19 08:40:05 +02:00
2026-08-19 11:28:01 +02:00
2026-07-29 12:27:46 +02:00
2025-09-29 18:25:09 +03:00
2026-03-23 11:57:44 +02:00
2025-09-04 18:08:39 +03:00
2025-07-28 21:29:29 +02:00
…
2025-09-29 18:25:09 +03:00
2024-12-02 17:51:17 +02:00
2024-12-02 11:35:34 +02:00
2026-08-19 11:28:01 +02:00
…
2025-11-28 12:56:27 +02:00
2025-11-28 12:56:27 +02:00
2026-08-19 11:28:01 +02:00
2026-06-21 15:32:20 +02:00
2026-08-19 08:40:05 +02:00
2024-10-03 13:24:43 +03:00
2024-09-09 13:50:38 +03:00
2026-08-19 11:28:01 +02:00
2026-01-31 14:08:54 +01:00
2025-03-27 08:01:47 +02:00
2026-07-29 12:27:46 +02:00
2026-07-29 12:27:46 +02:00
2026-08-19 08:40:05 +02:00
2026-04-01 10:49:05 +03:00
2025-07-28 19:40:10 +02:00