Bug #120326 Upgrade fails on partitioned tables due to stale THD error from stored procedure compilation

Submitted: 22 Apr 19:32 Modified: 23 Apr 6:17
Reporter: Shiv Bhatt Email Updates:
Status: In progress Impact on me:
None 
Category:MySQL Server: Data Dictionary Severity:S2 (Serious)
Version:8.4 OS:Any
Assigned to: CPU Architecture:Any
Tags: check_table_functions, partition, stored procedure, upgrade

[22 Apr 19:32] Shiv Bhatt
Description:
Upgrading from MySQL 8.0.40 to 8.4.7 fails with MY-014078 on a valid partitioned table when a stored procedure containing ENGINE=Memory exists on the instance.

During the upgrade, do_server_upgrade_checks runs two phases:
1. check_routines - compiles all stored procedures to validate them
2. check_table_funs - opens all tables with SQL functions in their definitions

In check_routines, if a stored procedure body contains CREATE TEMPORARY TABLE ... ENGINE=Memory, the parser calls resolve_engine() which fails because the MEMORY engine isn't loaded during early bootstrap. This sets error 1286 (ER_UNKNOWN_STORAGE_ENGINE) in the THD diagnostics area. The error is never cleared.

In check_table_funs, for partitioned tables with function-based expressions (e.g., PARTITION BY RANGE (month(col))), the code calls fix_partition_func which calls part_val_int. In MySQL 8.4, part_val_int checks current_thd->is_error() unconditionally after val_int(). It sees the stale error 1286 from the stored procedure check and returns failure, even though the partition expression evaluated correctly.

In MySQL 8.0, part_val_int only checked is_error() inside the null_value branch, so stale THD errors did not affect partition expression evaluation.

The behavior change in part_val_int (sql/sql_partition.cc):

8.0: https://github.com/mysql/mysql-server/blob/mysql-8.0.40/sql/sql_partition.cc
  *result = item_expr->val_int();
  if (item_expr->null_value) {
    if (current_thd->is_error()) return true;
    *result = LLONG_MIN;
  }
  return false;

8.4:  https://github.com/mysql/mysql-server/blob/mysql-8.4.0/sql/sql_partition.cc
  *result = item_expr->val_int();
  if (current_thd->is_error()) return true;  // unconditional
  if (item_expr->null_value) {
    *result = LLONG_MIN;
  }
  return false;

The error is not logged to the error log. The only visible symptom is:
  [MY-013135] Incorrect information in file: './db/table.frm'
  [MY-014078] Can not open table; functions in constraints, partitions, or virtual columns may have failed.
  [MY-010020] Data Dictionary initialization failed.

The .frm reference is misleading as there are no .frm files on MySQL 8.0 instances.

Confirmed via GDB: calling thd->clear_error() before fix_partition_func runs allows the upgrade to complete successfully.

Related: Bug #118347

How to repeat:
1. Install MySQL 8.0.40 and initialize a data directory.

2. Connect and create the following:

CREATE DATABASE test_repro;
USE test_repro;

DELIMITER //
CREATE PROCEDURE cleanup_proc()
BEGIN
  CREATE TEMPORARY TABLE IF NOT EXISTS temp_ids (
    id BIGINT PRIMARY KEY
  ) ENGINE=Memory;
  DROP TEMPORARY TABLE IF EXISTS temp_ids;
END //
DELIMITER ;

CREATE TABLE test_partition (
  id BIGINT NOT NULL AUTO_INCREMENT,
  dt DATETIME NOT NULL,
  PRIMARY KEY (id, dt)
) PARTITION BY RANGE (month(dt)) (
  PARTITION p01 VALUES LESS THAN (2),
  PARTITION p02 VALUES LESS THAN (3),
  PARTITION p03 VALUES LESS THAN (4),
  PARTITION p04 VALUES LESS THAN (13)
);

3. Stop the 8.0.40 server.

4. Start the 8.4.7 binary against the same data directory.

5. The upgrade fails with:

2026-04-22T19:16:50.383880Z 1 [ERROR] [MY-013135] [Server] Incorrect information in file: './test_repro/test_partition.frm'
2026-04-22T19:16:50.383906Z 1 [Warning] [MY-014078] [Server] Can not open table `test_repro`.`test_partition`; functions in constraints, partitions, or virtual columns may have failed.
2026-04-22T19:16:50.383919Z 1 [Note] [MY-014079] [Server] TABLE `test_repro`.`test_partition` = { PARTITION = { expr: "month(`dt`)"; };};
2026-04-22T19:16:50.386026Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed.

6. Drop the stored procedure and retry. The upgrade succeeds.

7. Create a fresh 8.0.40 instance with only the partition table (no stored procedure). Upgrade to 8.4.7. The upgrade succeeds.

Suggested fix:
Either:

1. Clear the THD error state in do_server_upgrade_checks between the check_routines and check_table_funs phases (sql/dd/impl/upgrade/server.cc).

2. Clear the THD error state in check_table_funs before processing each table (sql/dd/impl/upgrade/server.cc, before the open_table call).

3. Revert part_val_int to only check is_error() inside the null_value branch, matching the 8.0 behavior (sql/sql_partition.cc).
[23 Apr 6:32] Praveenkumar Hulakund
Thank you for reporting this issue. We will take a look at it.
[15 Sep 14:48] MySQL Admin
Posted by developer: Bug status updated to 'In progress'

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.040 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.