Bug #121492 Upgrade checker misses most FLOAT/DOUBLE AUTO_INCREMENT columns, so the 8.4 upgrade aborts after a clean check
Submitted: 13 Oct 0:27 Modified: 13 Oct 15:20
Reporter: Chelluru Vidyadhar Email Updates:
Status: Verified Impact on me:
None 
Category:Shell Upgrade Checker Severity:S3 (Non-critical)
Version:26.7.1, 9.7.1, 8.4.10 OS:Any
Assigned to: CPU Architecture:Any
Tags: checkForServerUpgrade, shell, upgrade, util

[13 Oct 0:27] Chelluru Vidyadhar
Description:
The columnDefinition check in util.checkForServerUpgrade() finds AUTO_INCREMENT columns of type FLOAT or DOUBLE, which MySQL 8.4 no longer supports and which abort the data dictionary upgrade. It identifies the type by comparing COLUMN_TYPE against the exact strings 'float' and 'double', so it only matches columns declared with no precision and no attributes.

modules/util/upgrade_checker/upgrade_check_creators.cc, lines 1699-1702 on current master:

```
SELECT table_schema, table_name, column_name,
       concat('##', column_type, 'AutoIncrement') as tag
FROM information_schema.columns
WHERE <<schema_and_table_filter>>
  AND column_type IN ('float', 'double')
  AND extra = 'auto_increment'
```

COLUMN_TYPE carries the precision and the attributes, so every one of these is an offending column the query does not match:

Declaration	COLUMN_TYPE	DATA_TYPE	matched?
FLOAT	float	float	yes
FLOAT(10,2)	float(10,2)	float	no
DOUBLE(20,4)	double(20,4)	double	no
FLOAT UNSIGNED	float unsigned	float	no
DOUBLE UNSIGNED	double unsigned	double	no
FLOAT(10,2) UNSIGNED	float(10,2) unsigned	float	no
FLOAT(10,2) UNSIGNED ZEROFILL	float(10,2) unsigned zerofill	float	no

Measured on a schema holding every AUTO_INCREMENT shape an 8.0 server accepts: the 8.4 server rejects 10 columns and refuses to start, and the checker reports 4. The six it misses are precisely those carrying a precision, UNSIGNED, or ZEROFILL.

So a user whose offending columns carry any of those attributes gets a clean result from the utility, starts the upgrade, and the server aborts during data dictionary initialization. 

How to repeat:
On MySQL 8.0 (reproduced on 8.0.46):

```
CREATE DATABASE si;
CREATE TABLE si.plain_float(id FLOAT NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE si.prec_float(id FLOAT(10,2) NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE si.plain_double(id DOUBLE NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE si.prec_double(id DOUBLE(20,4) NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE si.uns_float(id FLOAT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE si.uns_prec_float(id FLOAT(10,2) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE si.uns_double(id DOUBLE UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE si.zf_float(id FLOAT(10,2) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE si.real_ai(id REAL NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE si.dprec_ai(id DOUBLE PRECISION NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE si.int_ai (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
```

All eleven are accepted. Ten are approximate numeric; int_ai is a control.

Run the checker against an 8.4 target:

mysqlsh -- util check-for-server-upgrade --target-version=8.4.11 --include=columnDefinition

Observed: four errors. si.plain_float.id, si.plain_double.id, si.real_ai.id, si.dprec_ai.id.

Expected: ten errors. Everything except si.int_ai.id.

Now shut the 8.0 server down cleanly and start 8.4 on the same data directory (reproduced with 8.4.11). It exits non-zero, having named all ten:

```
[System] [MY-011090] Data dictionary upgrading from version '80023' to '80300'.
[ERROR]  [MY-015118] AUTO_INCREMENT is not supported with DOUBLE/FLOAT field.
                     Please consider fixing (Schema:si, Table:<name>, Column:id).
         ... one MY-015118 per column, ten in total:
         plain_float, prec_float, plain_double, prec_double, uns_float,
         uns_prec_float, uns_double, zf_float, real_ai, dprec_ai
[ERROR]  [MY-010020] Data Dictionary initialization failed.
[ERROR]  [MY-010119] Aborting
```

The server's check is type-based and catches all ten. The upgrade checker which uses string-based search and catches four.

Suggested fix:
Use DATA_TYPE instead of COLUMN_TYPE. DATA_TYPE is the bare type name with no precision and no attributes, which is exactly the granularity the server's own check uses:

```
SELECT table_schema, table_name, column_name,
       concat('##', data_type, 'AutoIncrement') as tag
FROM information_schema.columns
WHERE <<schema_and_table_filter>>
  AND data_type IN ('float', 'double')
  AND extra = 'auto_increment'
```

Verified against the same schema: matches all ten offending columns, does not match the INT control.

The tag expression has to change with it, and DATA_TYPE makes that fall out for free. 

DATA_TYPE yields ##floatAutoIncrement and ##doubleAutoIncrement for every variant, so both keys stay valid and no message entries are needed.

A prefix extraction such as SUBSTRING_INDEX(column_type, '(', 1) looks like the obvious fix and is not sufficient: it catches 8 of 10, still missing float unsigned and double unsigned, because those strings contain no ( to split on. It would also need the same normalization applied twice, in the filter and in the tag.