Console View
|
Categories: connectors experimental galera main |
|
| connectors | experimental | galera | main | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Merge branch '10.11' into 11.4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Merge remote-tracking branch 'github/11.4' into bb-11.4-serg | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
DerZc
34330257+DerZc@users.noreply.github.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-39969: Incorrect result of JSON_TABLE with BIT Problem: JSON_TABLE maps JSON numbers [0,1] to BIT(1) values [1,1]. The scalar helper passes decimal text to BIT's binary-string store, so the byte for '0' is 48 and is clipped to 1. Fix: Add Field::store_numeric() for number literals serialized as text, including fractions and exponents, and use it for JSON_TABLE numbers. BIT parses these literals as rounded unsigned integers and applies its existing range checks. Other fields retain their existing conversion; JSON strings and booleans retain their existing storage paths. Preserve the existing distinction between conversion warnings and JSON structural errors, so numeric overflow does not invoke ON ERROR. Extend json.json_table to cover BIT widths, unsigned boundaries, fractions, exponents, boolean/string/null inputs, other field types, conversion warnings and ON ERROR responses. Assisted-by: OpenAI Codex:gpt-6 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41253 RPM %pre scriptlet unconditionally resets a pre-existing mysql user's home directory to /nonexistent keep resetting to not writable, but use an existing path |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Andrei Elkin
andrei.elkin@pp.inet.fi |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41214 PURGE BINARY LOGS does not delete non-active binlog files PURGE BINARY LOGS could end with a warning instead of deleting files, as the test below shows when run on the base of this commit. The warning names a wrong reason. It follows an automatic purge that was refused by the slave guard, slave_connections_needed_for_purge: the automatic purge does not delete a binlog while it might still be needed by a slave, not necessarily a connected one, that is while fewer than the variable's number of slaves are connected. Since MDEV-34504 the manual PURGE is meant to ignore the guard. Yet it still protects a binlog that a slave is reading. Technically this was possible because the automatic and the manual purge share a code path, can_purge_log(), which cached the refusal and replayed it, under the reason of the first arm below, to any later purge: if (is_active(name) || (!is_relay_log && waiting_for_slave_to_change_binlog && purge_sending_new_binlog_file == sending_new_binlog_file && !strcmp(name, purge_binlog_name))) reason= "it is the current active binlog"; So "active" had to be read as "active or busy". The fix removes this duality too: the two arms are now separate and have their own reasons. The main issue is fixed by narrowing the busy arm with an additional `!interactive &&` conjunct, so that a manual PURGE never consults the cached refusal. Running the test below on an unfixed 11.4 server (source tree at commit 42038e1145d) fails with "Result length mismatch" and, in part 2, this diff against the recorded result: PURGE BINARY LOGS TO 'master-bin.000006'; +Warnings: +Note 1375 Binary log 'master-bin.000003' is not purged because it is the current active binlog SHOW WARNINGS; Level Code Message +Note 1375 Binary log 'master-bin.000003' is not purged because it is the current active binlog show binary logs; Log_name File_size +master-bin.000003 # +master-bin.000004 # +master-bin.000005 # master-bin.000006 # master-bin.000007 # master-bin.000008 # Test binlog.binlog_purge_stale_refusal_cache: the test sets slave_connections_needed_for_purge=1, binlog_expire_logs_seconds=0 and max_binlog_total_size=0 first and restores them at the end. It starts with RESET MASTER so that the binlog names, 000003 and so on, do not depend on the tests run before it in the same mtr environment. Part 1 is a control with nothing cached; part 2 makes an automatic purge refuse 000003 (the files must be older than binlog_expire_logs_seconds, hence --real_sleep 2 before the rotation) and then runs PURGE BINARY LOGS TO 'master-bin.000006', which must remove 000003..000005. As a workaround, a PURGE could work if the following settings are made before it, in this order: SET GLOBAL binlog_expire_logs_seconds=0, slave_connections_needed_for_purge=0; The second setting invalidates the cached refusal. The first one keeps the purge that this setting triggers from refusing and caching again. Note that both settings change the server's policy, not only this one PURGE: the time-based expiry and the slave guard are off until they are restored. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cleanup: put "bad frm" tests in one file | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41545 Unchecked get_clone() in ALTER of partitioned table crashes on out-of-memory get_clone() returns NULL on out-of-memory, but two of its callers in prep_alter_part_table() dereferenced the result without a check, so the server crashed: changed INTERVAL of SYSTEM_TIME partitioning ADD PARTITION under LOCK TABLES get_clone() itself did not check the allocation of Vers_part_info and dereferenced it. handle_alter_part_error() did not check the clone either. The clone only kept the DDL log entries after the table is closed. In the branch where DDL log recovery fails, write_log_completed() released the entries through lpt->part_info, which the table close may have freed, and release_log_entries() released the same entries again through the clone. That branch is not reachable now, as ddl_log_execute_entry() always returns false. The fix checks the allocation of Vers_part_info in get_clone() and the result of get_clone() in prep_alter_part_table() like the other callers there do. handle_alter_part_error() keeps a copy of DDL_LOG_STATE instead of the clone and passes it to write_log_completed() and release_log_entries(), which now take DDL_LOG_STATE. The redundant release_log_entries() after write_log_completed() is removed. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41449 ASAN server crash on corrupted frm make sure the declared (not actual) file length is not too small |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
replay loses infused statistics in stored functions Every sub-statement (stored function, trigger) replaced thd->opt_ctx_replay, leaking the top-level one, so the top-level tables were never restored and kept key_info->read_stats pointing into the freed statement mem_root. Saved and infused statistics were allocated on whatever arena was active, e.g. the stored function execution arena, freed before the restore. * create the replay object only for a top-level statement, and let sub-statements use it; restore only at the end of the top-level one * allocate everything the replay object owns in its own MEM_ROOT * empty the saved list after restoring Assisted-by: Claude:claude-5.5-opus |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Merge remote-tracking branch 'github/10.11' into bb-11.4-serg | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Hemant Dangi
hemant.dangi@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-35812: generate-ssl-certs.sh: remove bashism Issue: generate-ssl-certs.sh is a /bin/sh script but uses process substitution (<(printf ...)) for -extfile, which fails with plain sh. Solution: Write the extensions to a file in gcadir/ and pass it to -extfile. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Vladislav Vaintroub
vvaintroub@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-39183 CONNECT JDBC: JVM is loaded from bin\client on Windows GetJVM() only looked for %JAVA_HOME%\bin\client\jvm.dll, and for the RuntimeLib registry value of the "Java Runtime Environment" key. Since JDK 9 there is no "client" JVM, jvm.dll is in bin\server, and the JDK installers write JavaHome, but not RuntimeLib, under JavaSoft\JDK. Look for jvm.dll the way Java installations are laid out. Prefer bin\server over bin\client, in the JDK and in its jre subdirectory. Without connect_jvm_path (which stays exclusive, as before), try JAVA_HOME first, then the JavaSoft\{JDK|JRE} registry keys: CurrentVersion, then the RuntimeLib or JavaHome value of that version. Keep the first meaningful LoadLibrary or registry error (e.g. a 32/64 bit mismatch) rather than the "not found" of the last probe, reject over-long paths instead of truncating them, accept REG_EXPAND_SZ values, ignore an empty JAVA_HOME, and remove a stray printf to stdout. Tested manually with Oracle JDK 23: with JAVA_HOME unset (registry), with JAVA_HOME set, and with an invalid JAVA_HOME falling back to the registry. Assisted-By: Claude:claude-5.5-sonnet |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
fix LPAD() and INSERT() the same way as RPAD() they used to overwrite the charset of their arguments, this is incorrect and led to wrong results. Fix LPAD() and INSERT() not to do that anymore. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Alexander Barkov
bar@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41246 "Illegal mix of collations" on the mysql.user view This SQL script failed: SET NAMES latin1 COLLATE latin1_swedish_ci; CREATE OR REPLACE VIEW v1 AS SELECT 'Y' AS c1; SET NAMES big5 COLLATE big5_chinese_ci; SELECT * FROM v1 WHERE c1='y'; with the following error: ERROR 1267 (HY000): Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation '=' Note, latin1_swedish_ci and big5_chinese_ci are used here as examples. The error also happened with different collation combinations. Fix main idea: If two collations have equal comparison rules (known as "tailoring") on a given character repertoire, like latin1_swedish_ci and big5_chinese_ci on ASCII letters, then the "Illegal mix of collations" error can be avoided in a comparison operator. We can choose any of the sides as the operation effective collation - the result will be equal. This optimization is not applied when at least one side has an explicit COLLATE clause. Two explicit COLLATE clauses in one comparison are already illegal when the character sets are the same, so for consistency this stays illegal when the character sets differ too. Most important details: - Splitting enum_repertoire_t into smaller subsets, for better repertoire granularity. A variable holding a repertoire value can now have multiple MY_REPERTOIRE_XXX flags set. This patch implements detecting tailoring equality on these repertoires: * MY_REPERTOIRE_ASCII_DIGITS - [0..9] * MY_REPERTOIRE_ASCII_MINUS_DOT_DIGITS - [-.0..9], e.g. '-10.5'. It consists of the new bits MY_REPERTOIRE_ASCII_MINUS and MY_REPERTOIRE_ASCII_DOT. They were a part of MY_REPERTOIRE_ASCII_NOT_IDENT before. As a result, the numeric values of MY_REPERTOIRE_ASCII and MY_REPERTOIRE_UNICODE30 changed (223 and 255). * MY_REPERTOIRE_ASCII_ALNUM - [A..Z,a..z,0..9]. * MY_REPERTOIRE_ASCII_IDENT - ALNUM + underscore * MY_REPERTOIRE_ASCII - the entire range U+0000..U+007F - Adding a new virtual function "tailoring" in my_collation_handler_st. It returns the tailoring on the given repertoire for the given collation. If cs1->coll->tailoring(cs1, some_repertoire) returns {0,0}, it means the illegal mix optimization cannot be used for this collation on the given repertoire. If these calls: tr1= cs1->coll->tailoring(cs1, some_repertoire); tr2= cs2->coll->tailoring(cs2, some_repertoire); return both non-NULL results and tr1.str==tr2.str, then these collations are equal on the given repertoire and are mutually replaceable for a comparison operator, so "Illegal mix of collations" can be avoided. - Tailoring strings are shared constants my_tailoring_str_* (strings/strings_def.h). Tailorings are compared by the string pointer, so tailoring() implementations return strings only from these constants. The strings do not depend on PAD/NOPAD. - my_string_repertoire() for ucs2, utf16, utf32 and NONASCII 8bit character sets no longer stops at the first bad byte sequence with the repertoire found so far, which could be MY_REPERTOIRE_NONE (compatible with everything). It returns MY_REPERTOIRE_EXTENDED for such strings. A unit test was added into unittest/strings. - Adding CHARSET_INFO::is_ascii_superset(). It tells if a character set can store all ASCII characters (it is false for swe7). It is used in Item_func_conv_charset to calculate "safe", and in left_is_algorithmically_simpler() to prefer other character sets to those where ASCII strings cannot be converted safely. - DBUG_ASSERTs were added into mysys/charset.c, to check that the "tailoring" method is set in collation handlers when a collation is added: compiled-in, from ctype-extra.c, or loaded from Index.xml. - Adding a new function my_collations_equal_on_repertoire(cs1, cs2, repertoire) in strings/. It tells if two collations are equal on the repertoire, taking tailoring() results and PAD/NOPAD and the UCA version into account. Callers do not compare tailoring() results directly, so the way tailorings are compared (currently by the pointer to the shared constant string) is private to strings/ and can be extended later, e.g. for UCA collations on MY_REPERTOIRE_UNICODE30. - Adding a new method DTCollation::aggregate_by_tailoring(). Collations with different MY_CS_NOPAD are never compatible. UCA collations of different versions are not compatible on the repertoire with ASCII punctuation, as the UCA version affects its order (e.g. UCA-6.2.0 moved GRAVE ACCENT and CIRCUMFLEX ACCENT after PERCENT SIGN). - DTCollation::aggregate() now makes the repertoire of the result cover the repertoires of both sides in all successful branches. Before, set(dt) replaced the repertoire with the repertoire of the winner side only, so the result could have a too narrow repertoire, e.g. IF(1, 1.5, HEX(255)) had MY_REPERTOIRE_ASCII_ALNUM although the value '1.5' has a punctuation character. With the more granular repertoires this could wrongly allow mixing collations which are equal on ALNUM but different on punctuation. - Adding a new flag MY_COLL_ALLOW_BY_TAILORING. It indicates to DTCollation::aggregate() that the illegal mix optimization by repertoire can be used in the given context. MY_COLL_CMP_CONV now includes MY_COLL_ALLOW_BY_TAILORING. Note, only comparison operators pass this flag. Functions returning a string result do not pass this flag, because in operations like CONCAT(a,b) we still need to evaluate precisely the collation of the result - we cannot just choose a collation of one of the sides (even if they are compatible on the given repertoire). This also applies to ExtractValue() and UpdateXML(), which now aggregate their arguments without this flag. - As in my_repertoire_t the value MY_REPERTOIRE_ASCII is now a set of bits rather than a single bit, the way to detect "is only ASCII" repertoires has changed in the code. For example: // repertoire *IS* ascii if (repertoire == MY_REPERTOIRE_ASCII) has changed in multiple places in the code to // repertoire *HAS* only ascii characters if (my_repertoire_is_subset_of(repertoire, MY_REPERTOIRE_ASCII)) The new function my_repertoire_is_subset_of() in m_ctype.h is used for this purpose in C code. In C++ code DTCollation::repertoire_is_subset_of() is used, e.g.: if (collation.repertoire_is_subset_of(MY_REPERTOIRE_ASCII)) - Repertoire of some expressions was adjusted to the new meaning: * Item_null now has MY_REPERTOIRE_NONE (was ASCII). * MY_LOCALE::repertoire() now returns MY_REPERTOIRE_UNICODE30 (was EXTENDED). * Lex_string_with_metadata_st::repertoire(cs) now scans the string contents to detect the actual repertoire. * HEX() now has MY_REPERTOIRE_ASCII_ALNUM. * DATE_FORMAT() decides on MY_REPERTOIRE_EXTENDED using the locale which is actually used: the explicit third argument, or @@lc_time_names. It was always @@lc_time_names before. A non-constant locale argument is assumed to be non-ASCII. * QUOTE, MAKE_SET, EXPORT_SET, LPAD, RPAD, GROUP_CONCAT, JSON_ARRAY, JSON_OBJECT and JSON_OBJECTAGG add the repertoire of the extra characters they put into the result (quotes, separators, padding, brackets). * LOWER() and UPPER() add the letters of both cases to the repertoire, because the result can contain letters of the opposite case. In Turkish collations they also add MY_REPERTOIRE_EXTENDED, as an ASCII letter can be converted to a non-ASCII one (I -> dotless i). Unicode collations are detected by the new member casefold_info_st::can_convert_to_non_ascii_on_casefolding, simple 8bit collations by to_lower['I'] and to_upper['i']. - Lex_string_with_metadata_st::repertoire(cs) now scans a string literal for any byte oriented character set (mbminlen==1), not only for ASCII based ones. It was assumed to have the full repertoire for swe7, which is not ASCII based. The scan is done by Unicode code points, so swe7 strings with digits and letters get a narrow repertoire, while e.g. 0x5B (LATIN CAPITAL LETTER A WITH DIAERESIS in swe7) is non-ASCII. Therefore swe7_swedish_ci can be mixed with other collations now, in the same way as other collations with MY_CS_IDENT_CASEUP_CI. The test func_time was adjusted: a swe7 literal ' ull' with ASCII characters is now safe to convert, the error is still tested for '[ull'. - cp1250_czech_cs sorts -, . and 0..9 in the code point order, so it gets the MINUS_DOT_DIGITS tailoring. latin2_czech_cs gets only DIGITS, as it sorts the minus and the dot differently. Both were verified with ctype_digits_verify. - The tis620 collations now set CHARSET_INFO::tab_to_uni (was NULL), so my_charset_is_ascii_based() is true for tis620. It was false for tis620, although tis620 is ASCII compatible. Therefore tis620 string literals were always considered to have a non-ASCII repertoire, and the repertoire optimizations did not work for them. Now ASCII-only tis620 literals are detected as ASCII. This changes the result of subselect_extra_no_semijoin from an error to success. - tis620_thai_ci and tis620_thai_nopad_ci fold letters to lower case and then compare by the code point on the entire ASCII range (the Thai specific rules affect only non-ASCII characters). A new function my_tailoring_ascii_casedn_ci() returns tailorings for such collations on ALNUM, IDENT and ASCII. For example, the underscore sorts before the letters, unlike in the caseup tailorings. - New flags were added for CHARSET_INFO::state * MY_CS_ASCII_CASEUP_CI - for simple 8bit case insensitive collations. It means that this collation has no irregularities on the ASCII repertoire, and converts lower case letters to upper case ones, so the underscore sorts after the letters (with an upper to lower case conversion it would sort before the letters). * MY_CS_IDENT_CASEUP_CI - for simple 8bit case insensitive collations. It means that this collation has no irregularities on the IDENT repertoire (but can have irregularities say on punctuation). * MY_CS_ASCII_STD_UCA - for UCA collations. It means that a UCA collation does not reorder ASCII characters. * MY_CS_DIGITS_STD - for any collation. It means that the ASCII digits 0..9 are sorted in the code point order and are not tailored, and, for PAD collations, the space sorts before the digits. Strings of digits are compared in the same way in all such collations, even if they have irregularities on letters (latin7, cp866, czech, danish, turkish UCA, etc.), or differ by case sensitivity. It is detected from sort_order for 8bit collations, and from the tailoring rules for UCA collations. Collations with MY_CS_DIGITS_STD still must have the same PAD/NOPAD attribute. * MY_CS_ASCII_MINUS_DOT_DIGITS - for any collation. Means MY_CS_DIGITS_STD, and additionally the minus sorts before the dot, which sorts before the digits (and the space sorts before the minus in PAD collations). Strings like '-10.5' are compared in the same way in all such collations. It is detected from sort_order for simple 8bit collations (my_coll_init_simple()), and from the tailoring rules for UCA collations. For the multi-byte collations big5_chinese_ci, gbk_chinese_ci, gb2312_chinese_ci and sjis_japanese_ci it is declared by my_tailoring_ident_caseup_ci_generic(). The flags MY_CS_DIGITS_STD and MY_CS_ASCII_MINUS_DOT_DIGITS are stored in ctype-extra.c for compiled collations (conf_to_src.c prints them), and the detection is skipped for a collation which already has any of the repertoire flags (MY_CS_REPERTOIRE_FLAGS). - strings/conf_to_src.c was modified to detect and print MY_CS_ASCII_CASEUP_CI and MY_CS_IDENT_CASEUP_CI flags. - strings/ctype-extra.c was regenerated with new flags. - 8bit collations are not given MY_CS_ASCII_CASEUP_CI and MY_CS_IDENT_CASEUP_CI if they are PAD and the space does not sort before the digits. A shorter string is padded with spaces for comparison, so the position of the space matters even for strings without spaces ("ab" is compared to "abc" as "ab " to "abc"). A test collation latin1_space_after_letters_ci was added to mysql-test/std_data/ldml/ for this. ctype-extra.c does not change. - The initializer of my_collation_cs_handler in ctype-utf8.c (utf8mb3_general_cs, under HAVE_UTF8_GENERAL_CS) was fixed to match my_collation_handler_st: the missing get_id and get_collation_name members were added, so that eq_collation was not initialized in their place, and the new member "tailoring" is now set to my_tailoring_none. - Results of the existing tests func_str, func_test, ps, view and subselect_sj changed from "Illegal mix of collations" to success. In these tests ASCII-only strings were compared using collations with equal tailoring on ASCII, e.g. latin1_swedish_ci with latin2_general_ci (func_str, ps), koi8r_general_ci with latin1_swedish_ci (func_test), latin1_general_ci with latin1_swedish_ci on letters and digits (view), cp932_japanese_ci with latin1_swedish_ci (subselect_sj). Such comparisons are now allowed. Cases with collations that are still incompatible on ASCII, e.g. latin7_general_ci, were added to the tests and still fail. - Adding a number of MTR tests in plugin/func_test/mysql-test/func_test/. They display a tailoring by collation name and repertoire as returned by: cs->coll->tailoring(cs, some_repertoire) A dynamically linked plugin function collation_tailoring() was added for the purpose of these tests. Tailorings do not depend on PAD/NOPAD and on the UCA version, so the function shows "[nopad]" for NOPAD collations, and "[version X.Y.Z]" for UCA collations on the ASCII repertoire. The version is formatted by a new class UCAVersion, which uses a new method CharBuffer::append_uint8(). - Adding the test plugin/func_test/mysql-test/func_test/ ctype_caseup_ci_verify.test. It checks the order of ASCII characters for all collations declared "caseup CI" on the ASCII or IDENT range. - Adding the test plugin/func_test/mysql-test/func_test/ collation_tailoring_args.test. It checks the arguments of the plugin function collation_tailoring(): the repertoire passed by name or by number, and the NULL results for unknown names. - Adding the test plugin/func_test/mysql-test/func_test/ctype_ldml.test. It displays the tailorings of collations loaded at runtime from Index.xml: simple 8bit collations (flags detected from the weights) and Unicode collations (LDML rules which do or do not reorder ASCII). - Adding a number of MTR tests mysql-test/main/ctype_xxx_tailoring.test They display two-dimensional charts showing which collations are compatible on which repertoires. Tests for DATE_FORMAT() with an explicit locale were added to ctype_big5_tailoring.test, ctype_cp932_tailoring.test and ctype_latin5_tailoring.test, which also has the chart for latin5. - Adding a number of MTR tests in the form of the originally reported script for various collations: SELECT Insert_priv FROM mysql.user WHERE Insert_priv='...'; The repeated blocks of queries are shared through mysql-test/include/ ctype_tailoring_0{1,2,3}_mysql_user_Insert_priv*.inc. - Adding tests to ctype_cp932.test checking that ExtractValue() and UpdateXML() still raise "Illegal mix of collations". |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sutou Kouhei
kou@clear-code.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41285 ASAN heap-buffer-overflow mrn_get_string_between_quote/mrn_parse_table_param Fix a heap buffer overflow on escaped string in table/index comment parameter (#1249) `mrn_get_string_between_quote()` didn't advance `current_ptr` after it processed an escape sequence such as `\x`. So it wrote the escaped character repeatedly and overflowed the allocated buffer. It also didn't terminate the extracted string with `\0` when the string had an escape sequence. For example, the following SQL caused a heap buffer overflow: ```sql CREATE TABLE t1 (c INT) ENGINE=Mroonga COMMENT='engine "InnoDB\\x"'; ``` This also returns `NULL` when `mrn_my_malloc()` fails. Reported by Alice Sherepa. Found by Yuelin Wang. Assisted-by: Claude:claude-5.5-opus |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Jan Lindström
jan.lindstrom@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-39056 : sporadic test failures with galera.galera_toi_ddl_nonconflicting The test sent ALTER TABLE t1 ADD COLUMN f3 INTEGER; INSERT INTO t1 VALUES (NULL, 10000, 10000); from node_2 as a single --send. Nothing ordered that INSERT against the CREATE UNIQUE INDEX issued from node_1, so the second DDL could reach node_2 while the INSERT was still executing there and BF-abort it. The automatic autocommit retry then replicated with last_seen_seqno behind the seqno of the DDL and failed certification against its exclusive key on test.t1. As wsrep_retry_autocommit defaults to 1 there was no second retry and the client got ER_LOCK_DEADLOCK. Send only the ALTER TABLE and execute the INSERT after both DDL statements have completed on both nodes. Waiting for the second DDL by polling INFORMATION_SCHEMA.PROCESSLIST did not prove that it had been ordered either: wsrep_TOI_begin() sets the "Waiting to execute in isolation" stage before it replicates the writeset, so that state can be observed before the DDL has reached total order. Wait on node_2 for the new index to appear instead, which happens only once the DDL has been ordered behind the parked ALTER TABLE, and record on node_1 that neither DDL has been applied there while the first one is still parked. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Jan Lindström
jan.lindstrom@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41505 : Sql_cmd_show_routine_code::execute does not call wsrep_sync_wait() There was no wsrep_sync_wait on Sql_cmd_show_routine_code::execute. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
DerZc
34330257+DerZc@users.noreply.github.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41067: Fix JSON_OVERLAPS for nested arrays Problem: JSON_OVERLAPS treats unequal nested arrays as equal when only one parser reaches the array end. Requiring both ends also exposes a cleanup issue: scanning ']' moves stack_p to the parent, so skipping the current level consumes parent elements. This misses the common [2] in [[1],[2]] and [[],[2]], and can skip unequal recursive elements. Fix: Require both parsers to reach JST_ARRAY_END. Remember their array levels before comparing and skip to those saved levels after completed comparisons and mismatches, preserving parent siblings. Explain why the saved levels are needed. Add regression coverage for both argument orders, unequal lengths, empty arrays, recursive comparisons, type mismatches, array order and a later common object member. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sutou Kouhei
kou@clear-code.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Fix auto directory creation for absolute mroonga_database_path_prefix (#1166) mkdir_p() tried stat("") and mkdir("") for the leading directory separator of an absolute path and gave up. So we couldn't create database directory automatically for absolute mroonga_database_path_prefix such as "/var/lib/mroonga/". This also treats EEXIST from mkdir() as success because another process may create the directory after our stat(). Assisted-by: Claude:claude-5.5-opus |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41467 mbstream insufficient path validation in REMOVE and RENAME chunks apply the check from file_entry_new() also to other file operations also: swap names in the the rename error message |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Merge branch '10.11' into 11.4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41458 Assertion `n > 0 && n < SINUSES_CALCULATED*2+1' failed in get_n_sincos() With tiny *ex and *ey the sum of squares underflows and q becomes inf, use hypot() which is under- and overflow safe. Also, fix ab/(d*d) divison, for good measure |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| workaround for https://bugzilla.redhat.com/show_bug.cgi?id=2390105 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sutou Kouhei
kou@clear-code.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41287 ASAN: stack-buffer-overflow in strcpy/mrn::DatabaseRepairer::detect_paths/mrn::DatabaseRepairer::each_database Fix a buffer overflow with long mroonga_database_path_prefix (#1159) Reported by Yuelin Wang. Thanks!!! We used fixed size buffers (MRN_MAX_PATH_SIZE) for database paths built from mroonga_database_path_prefix. So a long mroonga_database_path_prefix caused a buffer overflow. This uses std::string for them. We don't need to check path length in Mroonga because Groonga reports an error for too long path. Assisted-by: Claude:claude-5.5-opus |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-40041 Assertion `fixed()' failed in Item_func_connection_id::val_int on INSERT w/ TRIGGER Under LOCK TABLES close_thread_tables() cleans up session-dependent virtual column expressions (vcol_cleanup_expr()) of all tables in thd->open_tables, because they are not closed at the end of the statement. A trigger sub-statement also calls close_thread_tables() at its end, so a BEFORE INSERT trigger cleaned up the expressions of the table the outer INSERT was still writing to. Then TABLE::update_virtual_fields() evaluated the unfixed CONNECTION_ID() and failed the assertion. The fix skips vcol_cleanup_expr() in close_thread_tables() when in sub-statement. The outer statement cleans up the expressions when it closes its tables. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
DerZc
34330257+DerZc@users.noreply.github.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-39194: Fix DISTINCT bit and hex aggregation Problem: SUM(DISTINCT b'1100') returns 9 instead of 12. The hybrid hex/bit literal handler uses the default DOUBLE temporary field, so its byte length becomes a DOUBLE(M,0) display width and clips the numeric value. Fix: Override numeric DISTINCT field construction for hybrid hex and bit literals to allocate an unsigned Field_longlong directly. Preserve argument-based field selection for other types so DISTINCT retains the input expression's precision and scale, including decimal AVG inputs. Extend main.sum_distinct to cover bit and hex literals, zero, byte and unsigned 64-bit boundaries, duplicates, AVG, COUNT and decimal scale. Recreated-by: Georgi "Joro" Kodinov <[email protected]> |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-39074 trans_rollback_stmt(THD *): Assertion `! thd->in_sub_stmt' failed. slave_close_thread_tables() unconditionally called trans_commit_stmt()/trans_rollback_stmt(), which assert !thd->in_sub_stmt. A BINLOG statement with malformed base64 payload executed from an AFTER INSERT trigger hits this: on decode failure, mysql_client_binlog_statement() sets thd->is_error() and calls slave_close_thread_tables() from within the trigger's sub-statement. The fix refuses BINLOG in stored routines, triggers, events and anonymous blocks with ER_SP_BADSTATEMENT at parse time, like LOCK, HANDLER etc. Dynamic SQL (EXECUTE IMMEDIATE, EXECUTE) run from a routine bypasses the parser check, so mysql_client_binlog_statement() checks spcont as well: in a stored procedure in_sub_stmt is 0, but the decoded events assert !spcont in reset_for_next_command(). 1. BINLOG statement executed from a trigger, SF or SP is disabled by the patch: Row events (Rows_log_event) open their target table via a one-shot check that only fires at the top of a fresh statement. Inside a trigger, the table is never opened this way. It may be fixed by reusing query_tables, but: - find_locked_table() matches only by table name -- it could return the TABLE instance the enclosing statement is actively writing through, not an idle one. Reusing it would require pre-saving its state: record[0]/bitmaps/handler/etc. (and would bypass ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG) - set_stmt_row_injection()/set_time() calls would mutate thd->lex, which at that point is main_lex -- shared with the enclosing statement, not something safe to touch. Statement events (Query_log_event) run the embedded query via mysql_parse(): it bundles lex_start(), reset_for_next_command() and parse_sql() as one unit meant for a genuinely new top-level statement, not a one-off nested parse. Calling parse_sql() directly instead avoids that, but then we own everything mysql_parse() was doing for us: a private LEX and a private Query_arena (or allocations land on main_lex/whatever arena is currently active, shared with the enclosing statement), plus calling mysql_execute_command() ourselves afterwards. In any case, DML for query_tables cannot be done due to ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG reasons explained above. 2. PS for BINLOG statement still works and needs a leak fix for statement events: A BINLOG statement decoding to a Query_log_event, executed via PREPARE/EXECUTE, leaked its nested query's allocations onto the PS's own persistent arena: thd->stmt_arena pointed at it while mysql_parse() ran the decoded query. Second EXECUTE asserted on ROOT_FLAG_READ_ONLY, since PROTECT_STATEMENT_MEMROOT marks that arena read-only after a successful execution. The fix redirects thd->stmt_arena to thd itself for the duration of the event application, so stmt_arena->is_conventional() reads true and activate_stmt_arena_if_needed() (called e.g. from save_leaf_tables()) never redirects allocations to the PS's arena in the first place. Harmless for what it's protecting: leaf_tables_exec is normally cached on the persistent arena so a repeatedly-executed statement's SELECT_LEX doesn't rebuild it every time, but our SELECT_LEX is torn down and reparsed fresh (due to mysql_parse() semantics) on every EXECUTE, so there's nothing to cache here regardless of which arena is used. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41540 filesort assert crash on a huge sort key sort key could go over 4GB making sort length to wrap around. let's limit sort key length by 2GB - still ridiculously unrealistically large but far enough from 4GB so that any additions in the code below would still be safe. The error is somewhat confusing, but, again, only someone who pushes the margins to exploit memory bugs will ever see it. Additionally min_sort_memory calculations are done as uint and can wrap around too, allocating later over 4GB memory not constrained by @@sort_buffer_size |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MDEV-41431 LOAD_FILE checks for is_secure_file_path() one path but opens another | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Revert "MDEV-36832 UPDATE...IN(SELECT) acquires spurious gap locks on FK index" This reverts commit f4a3b69bdf14. As agreed with the contributor. It breaks 11.4. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-39074 trans_rollback_stmt(THD *): Assertion `! thd->in_sub_stmt' failed. slave_close_thread_tables() unconditionally called trans_commit_stmt()/trans_rollback_stmt(), which assert !thd->in_sub_stmt. A BINLOG statement with malformed base64 payload executed from an AFTER INSERT trigger hits this: on decode failure, mysql_client_binlog_statement() sets thd->is_error() and calls slave_close_thread_tables() from within the trigger's sub-statement. The fix refuses BINLOG in stored routines, triggers, events and anonymous blocks with ER_SP_BADSTATEMENT at parse time, like LOCK, HANDLER etc. Dynamic SQL (EXECUTE IMMEDIATE, EXECUTE) run from a routine bypasses the parser check, so mysql_client_binlog_statement() checks spcont as well: in a stored procedure in_sub_stmt is 0, but the decoded events assert !spcont in reset_for_next_command(). 1. BINLOG statement executed from a trigger, SF or SP is disabled by the patch: Row events (Rows_log_event) open their target table via a one-shot check that only fires at the top of a fresh statement. Inside a trigger, the table is never opened this way. It may be fixed by reusing query_tables, but: - find_locked_table() matches only by table name -- it could return the TABLE instance the enclosing statement is actively writing through, not an idle one. Reusing it would require pre-saving its state: record[0]/bitmaps/handler/etc. (and would bypass ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG) - set_stmt_row_injection()/set_time() calls would mutate thd->lex, which at that point is main_lex -- shared with the enclosing statement, not something safe to touch. Statement events (Query_log_event) run the embedded query via mysql_parse(): it bundles lex_start(), reset_for_next_command() and parse_sql() as one unit meant for a genuinely new top-level statement, not a one-off nested parse. Calling parse_sql() directly instead avoids that, but then we own everything mysql_parse() was doing for us: a private LEX and a private Query_arena (or allocations land on main_lex/whatever arena is currently active, shared with the enclosing statement), plus calling mysql_execute_command() ourselves afterwards. In any case, DML for query_tables cannot be done due to ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG reasons explained above. 2. PS for BINLOG statement still works and needs a leak fix for statement events: A BINLOG statement decoding to a Query_log_event, executed via PREPARE/EXECUTE, leaked its nested query's allocations onto the PS's own persistent arena: thd->stmt_arena pointed at it while mysql_parse() ran the decoded query. Second EXECUTE asserted on ROOT_FLAG_READ_ONLY, since PROTECT_STATEMENT_MEMROOT marks that arena read-only after a successful execution. The fix redirects thd->stmt_arena to thd itself for the duration of the event application, so stmt_arena->is_conventional() reads true and activate_stmt_arena_if_needed() (called e.g. from save_leaf_tables()) never redirects allocations to the PS's arena in the first place. Harmless for what it's protecting: leaf_tables_exec is normally cached on the persistent arena so a repeatedly-executed statement's SELECT_LEX doesn't rebuild it every time, but our SELECT_LEX is torn down and reparsed fresh (due to mysql_parse() semantics) on every EXECUTE, so there's nothing to cache here regardless of which arena is used. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41473 more mysql_json plugin OOB reads * check that `element_count` doesn't point beyond the data end also fixed: * UB in `expr<<28` shift in `read_variable_length()` * off-by-one in `parse_mysql_scalar()` * decimal sanity in `parse_mysql_scalar()` |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MDEV-39625 plugin/auth_pam/testing/CMakeLists.txt breaks INSTALL_MYSQLTESTDIR= suppression | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-25176 Shutdown hangs if event scheduler is started during shutdown SET GLOBAL event_scheduler=1 executed by a connection during shutdown could start the scheduler thread after close_connections() called Events::stop(). Nothing stops this thread and close_connections() waits for it forever. Now it hangs instead of a crash since MDEV-30260 fix: it moved deinit() from close_connections() to clean_up(), so the scheduler is not freed under the running thread anymore. The fix makes Event_scheduler::start() do nothing when abort_loop is set. abort_loop is set before close_connections() and is checked under LOCK_scheduler_state, which stop() also takes, so the scheduler is either started before stop() and stopped by it, or not started at all. No error needed: the server is shutting down. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Oleksandr Byelkin
sanja@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-32401 expression cache lead to crash if table of wrong type created and the cache switched off 1) take into account TMP_TABLE_ALL_COLUMNS when we are modifying agg_item->result_field 2) remove unused now "bool materialized_subquery;" Co-Authored-By: Claude Opus 5.5 <[email protected]> |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41543 Changing INTERVAL of SYSTEM_TIME partitioning does not move history ALTER TABLE ... PARTITION BY SYSTEM_TIME with a changed INTERVAL or STARTS on a table already partitioned by SYSTEM_TIME took the fast ALTER path, which only rewrites the table definition. The history rows stayed where the old layout put them, so after the ALTER they were in wrong partitions. An unchanged interval took the copy path instead. MDEV-29873 replaced memcmp() of the intervals, which is true when they differ, with interval_t::operator==, which is true when they are equal, and lost the negation. The copy path was also broken: it assigned the whole vers_info of the new partitioning spec to the cloned partition info, now_part and hist_part included. The ALTER does not list partitions, so now_part became NULL and check_partition_info() failed with ER_VERS_WRONG_PARTS for a table with explicit partitions (MDEV-33370 test case). The fix negates the comparison again (now with interval_t::operator!=), so a changed interval rebuilds the table and redistributes the history. It copies only interval, limit and auto_hist from the new spec and keeps now_part and hist_part of the existing partitions. Without STARTS the start of the interval defaults to the current time rounded down to the INTERVAL unit. So ALTER with the same INTERVAL and no STARTS usually gets a different start and now rebuilds the table. Vers_part_info::operator=, which copied now_part and hist_part and had no other callers, is deleted. Fast ALTER was also chosen when the same statement changed the table definition, e.g. ADD COLUMN with the same INTERVAL and STARTS, or DROP COLUMN with LIMIT. It wrote the new .frm, but the partitions kept the old record layout. Now any change of the table definition (alter_info->flags) takes the copy path. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MDEV-39624 storage/connect/CMakeLists.txt: unguarded generator expression variable causes fatal error at cmake generate phase | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41496 OOB write with RPAD() crash and multi-byte charsets and uservar Item_func_rpad::val_str was expecting all arguments converted to the collation.collation, but user variable, if modified, could change its charset mid-query. Fix: changing and querying a uservar in the same statement is documented to be UB. Thus, ignore the current charset of arguments, treat them as strings in the expected collation.collation. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Khaled Riyad
khaled57.dev@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-37563 Crash on a FOR loop with a row comparison in the upper bound Both bounds of a FOR loop, and all parameters of a cursor FOR loop, are parsed before their instructions are added. add_instr() then gave all their items to the first instruction, and in a trigger also all NEW and OLD fields. So a row comparison used by a later instruction was cleaned up by the wrong one, on the next CALL, after its memory had already been freed. This crashed in Arg_comparator::cleanup(). Give each instruction only the items of its own expression, and its own trigger fields. To find them, cut THD::free_list at the newest item of each expression, starting with the oldest expression. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||