Skip to content

fix(system): Database Tables list empty on MySQL 8.0.18#16855

Open
Ibochkarev wants to merge 11 commits intomodxcms:3.xfrom
Ibochkarev:fix/14976-database-tables-mysql8
Open

fix(system): Database Tables list empty on MySQL 8.0.18#16855
Ibochkarev wants to merge 11 commits intomodxcms:3.xfrom
Ibochkarev:fix/14976-database-tables-mysql8

Conversation

@Ibochkarev
Copy link
Copy Markdown
Collaborator

What does it do?

  • Resolves the current database name for MySQL 8 via SELECT DATABASE() with config fallback (MySQL 8 does not expose it in SHOW TABLE STATUS the same way).
  • Casts Data_length, Data_free, Index_length to int to handle NULL/string values returned by SHOW TABLE STATUS on MySQL 8.
  • Computes Effective_size as max(0, dataLength - dataFree) to avoid negative or invalid values.
  • Refactors the processor: extracts formatTableRow(), caches hasPermission('settings') and manager_log table name before the loop; adds type hints for the helper.

Why is it needed?

On MySQL 8.0.18, Reports → System Information → Database Tables returns an empty list because the processor relied on database name and numeric fields in ways that are no longer valid (different SHOW TABLE STATUS behavior and schema).

How to test

  1. Use MySQL 8.0.18 (or compatible 8.x).
  2. Go to Reports → System Information → Database Tables.
  3. Confirm the list of tables is populated with name, rows, size, and effective size.
  4. Optionally run core/vendor/bin/phpcs --standard=phpcs.xml core/src/Revolution/Processors/System/DatabaseTable/mysql/GetList.php to ensure coding standards pass.

Related issue(s)/PR(s)

Resolves #14976

@Ibochkarev Ibochkarev force-pushed the fix/14976-database-tables-mysql8 branch from a0c8e85 to c9d5a99 Compare February 22, 2026 16:30
- Resolve database name via SELECT DATABASE() with config fallback for MySQL 8
- Cast Data_length, Data_free, Index_length to int to handle NULL in SHOW TABLE STATUS
- Compute Effective_size as max(0, dataLength - dataFree)
- Extract formatTableRow(), cache permission and manager_log table name before loop
- Add type hints for formatTableRow parameters

Resolves modxcms#14976
@Ibochkarev Ibochkarev force-pushed the fix/14976-database-tables-mysql8 branch from c9d5a99 to bd6b08c Compare February 22, 2026 16:54
@biz87
Copy link
Copy Markdown

biz87 commented Feb 25, 2026

Code Review

Summary

Fixes #14976: Database Tables grid returns empty on MySQL 8.0.18. Three key changes: resolve DB name via SELECT DATABASE() instead of config, cast Data_length/Data_free/Index_length to (int) for NULL handling, and refactor the loop body into formatTableRow() with cached permission checks. Single file changed: core/src/Revolution/Processors/System/DatabaseTable/mysql/GetList.php (+60/-13).

Issues

1. Other processors share the same getOption('dbname') problem

Truncate.php:26, Optimize.php:24, OptimizeDatabase.php:31 all use $this->modx->getOption('dbname') directly. If this value is unreliable on MySQL 8, those processors are broken too. Consider moving getDatabaseName() to the base class or at least opening a follow-up issue.

2. No null check on $c->stmt before execute()

Inherited from the original code, but since the file is being refactored and getDatabaseName() already has defensive checks, this should be guarded too:

$c = new xPDOCriteria($this->modx,
    'SHOW TABLE STATUS FROM ' . $this->modx->escape($dbName));
if ($c->stmt === null) {
    return [];
}
$c->stmt->execute();

3. Silent empty return without logging

if ($dbName === null || $dbName === '') {
    return [];
}

The user sees an empty grid with no indication of what went wrong — the same symptom as the original bug. Consider adding a log entry:

if ($dbName === null || $dbName === '') {
    $this->modx->log(modX::LOG_LEVEL_ERROR, '[DatabaseTable/GetList] Could not determine database name');
    return [];
}

Suggestions

1. getDatabaseName() return type vs getOption() return type

The docblock promises string|null, but $this->modx->getOption('dbname') formally returns mixed. Consider explicit casting:

return (string) $this->modx->getOption('dbname') ?: null;

2. privateprotected visibility

MODX codebase conventionally uses protected for non-public methods to allow extension via subclasses. Both formatTableRow() and getDatabaseName() are private without a clear reason to restrict inheritance.

Assessment

Good quality PR. The (int) casting is the essential fix — MySQL 8 can return NULL for Data_length/Data_free/Index_length on InnoDB tables, breaking all arithmetic. The getDatabaseName() method is a reasonable additional safeguard. Loop optimization (caching hasPermission() and table name concatenation) is a welcome improvement. The implicit canOptimize bug (original code compared a formatted string like "1.5 KB" > 0 instead of the raw integer) is also correctly fixed. PHPStan and PHPCS clean on the changed file.

Verdict

Request changes — minor fixes needed (items 2–3 above, item 1 as follow-up issue).

…processor

- Added logging for cases where the database name cannot be determined.
- Enhanced error handling by returning early if the statement is null.
- Changed access modifiers for formatTableRow() and getDatabaseName() methods to protected for better extensibility.
@smg6511
Copy link
Copy Markdown
Collaborator

smg6511 commented Mar 19, 2026

One thing to note here is that the empty list problem will only be able to be verified with this specific version (and perhaps other early 8.x ones) of mysql. I'm running 8.0.44 in my test environment and cannot replicate the issue there. Nonetheless, there are a couple upsides to this PR—some safeguards, optimizations, and logging, as well as only formatting a column value with an optimization link when there is one to be done (e.g., in the overhead col). Will review further later today/tomorrow...

Copy link
Copy Markdown
Collaborator

@smg6511 smg6511 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few details I'd like to see covered to move this forward. Also, the following Lexicon entries would need to be added into system_info.inc.php in addition to the requested changes below:

$_lang['database_query_err_dbname_empty'] = 'Query for current database name returned an empty value.';
$_lang['database_query_err_table_stat'] = 'Query for TABLE STATUS from [[+db]] returned a null result.';

Lastly, if anyone (aside from Ivan) can easily test this against mysql 8.0.18 that'd be ideal. I currently don't have a flexible setup on the mysql side to be able to check multiple minor versions.

Ivan: It's important to note that if you look at the original issue's conversation you'll find the problem may have had more to do with XPDO's parseDSN at the time than mysql itself. That and the issue was reported for MODX 2.x. There needs to be more focus when throwing these issues into the AI “blender” ;-)

Comment thread core/src/Revolution/Processors/System/DatabaseTable/mysql/GetList.php Outdated
Comment thread core/src/Revolution/Processors/System/DatabaseTable/mysql/GetList.php Outdated
Comment thread core/src/Revolution/Processors/System/DatabaseTable/mysql/GetList.php Outdated
Comment thread core/src/Revolution/Processors/System/DatabaseTable/mysql/GetList.php Outdated
Ibochkarev and others added 5 commits March 20, 2026 11:16
…ist.php

Co-authored-by: Jim Graham <jim@pixelsandstrings.com>
…ist.php

Co-authored-by: Jim Graham <jim@pixelsandstrings.com>
…ist.php

Co-authored-by: Jim Graham <jim@pixelsandstrings.com>
…ist.php

Co-authored-by: Jim Graham <jim@pixelsandstrings.com>
…ist.php

Co-authored-by: Jim Graham <jim@pixelsandstrings.com>
@Ibochkarev Ibochkarev requested a review from smg6511 March 20, 2026 05:17
@smg6511
Copy link
Copy Markdown
Collaborator

smg6511 commented Mar 20, 2026

@Ibochkarev Hey - just a reminder you'll need to add the Lexicon entries I mentioned above.

@Ibochkarev
Copy link
Copy Markdown
Collaborator Author

@Ibochkarev Hey - just a reminder you'll need to add the Lexicon entries I mentioned above.

Done

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 20, 2026

Codecov Report

❌ Patch coverage is 0% with 37 lines in your changes missing coverage. Please review.
✅ Project coverage is 21.66%. Comparing base (af7a969) to head (3cddb95).
⚠️ Report is 11 commits behind head on 3.x.

Files with missing lines Patch % Lines
.../Processors/System/DatabaseTable/mysql/GetList.php 0.00% 37 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##                3.x   #16855      +/-   ##
============================================
+ Coverage     21.64%   21.66%   +0.01%     
- Complexity    10764    10793      +29     
============================================
  Files           566      566              
  Lines         33005    33171     +166     
============================================
+ Hits           7144     7185      +41     
- Misses        25861    25986     +125     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@smg6511 smg6511 self-assigned this Mar 21, 2026
Comment thread core/src/Revolution/Processors/System/DatabaseTable/mysql/GetList.php Outdated
Comment thread core/src/Revolution/Processors/System/DatabaseTable/mysql/GetList.php Outdated
Comment thread core/src/Revolution/Processors/System/DatabaseTable/mysql/GetList.php Outdated
Ibochkarev and others added 3 commits March 23, 2026 10:23
…ist.php

Co-authored-by: Jim Graham <jim@pixelsandstrings.com>
…ist.php

Co-authored-by: Jim Graham <jim@pixelsandstrings.com>
…ist.php

Co-authored-by: Jim Graham <jim@pixelsandstrings.com>
@Ibochkarev Ibochkarev requested a review from smg6511 March 23, 2026 04:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reports > System Information > Database Tables Grid not loading on MySQL 8.0.18

3 participants