1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00
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-08-19 11:28:01 +02:00
2026-08-19 11:28:01 +02:00
2026-05-08 08:11:03 +02:00
2026-06-15 12:50:45 +02:00
2026-08-19 11:28:01 +02:00
2026-05-08 08:00:01 +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-07-29 12:27:46 +02:00
2026-07-29 12:27:46 +02:00
2026-06-15 15:15:10 +02:00
2026-07-29 12:27:46 +02:00
…
2026-07-29 12:27:46 +02:00
2026-04-24 22:19:40 +02:00
2026-07-29 12:27:46 +02:00
2026-06-15 15:15:10 +02:00
2026-07-28 13:14:38 +02:00
2026-07-29 12:27:46 +02:00
2026-08-19 11:28:01 +02:00
2026-08-19 11:28:01 +02:00
…
2026-06-15 12:50:45 +02:00
2026-05-27 14:29:16 -04:00

Code status:

  • Appveyor CI status ci.appveyor.com

MariaDB: The innovative open source database

MariaDB was designed as a drop-in replacement of MySQL(R) with more features, new storage engines, fewer bugs, and better performance.

MariaDB is brought to you by the MariaDB Foundation and the MariaDB Corporation. Please read the CREDITS file for details about the MariaDB Foundation, and who is developing MariaDB.

MariaDB is developed by many of the original developers of MySQL who now work for the MariaDB Corporation, the MariaDB Foundation and by many people in the community.

MySQL, which is the base of MariaDB, is a product and trademark of Oracle Corporation, Inc. For a list of developers and other contributors, see the Credits appendix. You can also run 'SHOW authors' to get a list of active contributors.

A description of the MariaDB project and a manual can be found at:

https://mariadb.org

https://mariadb.com/docs/

https://mariadb.com/docs/release-notes/community-server/about/compatibility-and-differences/mariadb-vs-mysql-features

https://mariadb.com/docs/release-notes/community-server/about/compatibility-and-differences/mariadb-vs-mysql-compatibility

https://mariadb.com/docs/release-notes

Getting the code, building it and testing it

Refer to the following guide: https://mariadb.org/get-involved/getting-started-for-developers/get-code-build-test/ which outlines how to build the source code correctly and run the MariaDB testing framework, as well as which branch to target for your contributions.

Help

More help is available from the Maria Discuss mailing list https://lists.mariadb.org/postorius/lists/discuss.lists.mariadb.org/ and MariaDB's Zulip instance, https://mariadb.zulipchat.com/

Licensing


MariaDB is specifically available only under version 2 of the GNU General Public License (GPLv2). (I.e. Without the "any later version" clause.) This is inherited from MySQL. Please see the README file in the MySQL distribution for more information.

License information can be found in the COPYING file. Third party license information can be found in the THIRDPARTY file.


Bug Reports

Bug and/or error reports regarding MariaDB should be submitted at: https://jira.mariadb.org

For reporting security vulnerabilities, see our security-policy.

The code for MariaDB, including all revision history, can be found at: https://github.com/MariaDB/server

Description
Сервер MariaDB - это разработанный сообществом форк сервера MySQL
https://mariadb.org Readme 2.7 GiB
Languages
MariaDB\ 71.8%
C++ 16.5%
C 10.3%
Shell 0.5%
Perl 0.4%
Other 0.3%