Skip to content

Fix #19539 - Insert/edit form error with invisible columns - #20565

Open
xmaks82 wants to merge 2 commits into
phpmyadmin:QA_5_2from
xmaks82:insert-edit-invisible-columns-52
Open

xmaks82 wants to merge 2 commits into
phpmyadmin:QA_5_2from
xmaks82:insert-edit-invisible-columns-52

Conversation

@xmaks82

@xmaks82 xmaks82 commented Oct 23, 2026

Copy link
Copy Markdown

Fixes #19539

Same fix as #20560, for QA_5_2 as suggested there.

SELECT * does not return invisible columns (MySQL INVISIBLE, including the generated invisible primary key my_row_id, and MariaDB INVISIBLE), but the insert/edit form iterates over all table columns and reads the result metadata by position. With an invisible column in the table, the metadata of the following columns is shifted and the form shows Undefined array key warnings.

This leaves invisible columns out in InsertEdit::getTableColumns(), so the form columns and the result metadata line up again. Invisible columns are not shown in the form, the same as in SELECT *.

Test: testGetTableColumnsSkipsInvisibleColumns.

SELECT * does not return invisible columns, so the result metadata of
the following columns was read at the wrong position. Leave invisible
columns out of the columns used for the form.

Signed-off-by: Магда М.Г. <mail@mgmagda.ru>
@codecov

codecov Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 50.44%. Comparing base (9db6360) to head (6b2dd37).
⚠️ Report is 3 commits behind head on QA_5_2.

Additional details and impacted files
@@             Coverage Diff              @@
##             QA_5_2   #20565      +/-   ##
============================================
+ Coverage     50.42%   50.44%   +0.02%     
- Complexity    17261    17264       +3     
============================================
  Files           607      607              
  Lines         68333    68340       +7     
============================================
+ Hits          34455    34476      +21     
+ Misses        33878    33864      -14     
Flag Coverage Δ
dbase-extension 50.28% <100.00%> (-1.14%) ⬇️
guzzlehttp/psr7-psr-7 50.79% <100.00%> (-0.55%) ⬇️
laminas/laminas-diactoros-psr-7 49.52% <100.00%> (-1.28%) ⬇️
nyholm/psr7-psr-7 51.29% <100.00%> (+1.10%) ⬆️
recode-extension 50.14% <100.00%> (+0.03%) ⬆️
slim/psr7-psr-7 50.19% <100.00%> (+0.05%) ⬆️
unit-7.2 51.31% <100.00%> (-0.04%) ⬇️
unit-7.3 50.19% <100.00%> (+0.75%) ⬆️
unit-7.4 49.47% <100.00%> (+0.03%) ⬆️
unit-8.0 49.48% <100.00%> (-0.03%) ⬇️
unit-8.1 49.52% <100.00%> (-1.35%) ⬇️
unit-8.2 49.45% <100.00%> (-0.02%) ⬇️
unit-8.3 49.45% <100.00%> (-0.01%) ⬇️
unit-8.4 49.43% <100.00%> (-0.05%) ⬇️
unit-8.5 49.51% <100.00%> (+0.03%) ⬆️
unit-8.6 49.51% <100.00%> (+0.08%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 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.

@williamdes williamdes left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Look okay for me, I will leave the review to @kamil-tekiela

@kamil-tekiela

Copy link
Copy Markdown
Contributor

If all you want to do is skip this column look at the line 2516. Filtering like this in getTableColumns is a very nasty way of solving this problem.

@xmaks82

xmaks82 commented Oct 23, 2026

Copy link
Copy Markdown
Author

Skipping at line 2516 alone is not enough: getHtmlForInsertEditFormColumn() reads getFieldsMeta($currentResult)[$columnNumber]->length (line 2134) by the table column position, and the result of SELECT * has no entry for the invisible column. With the GIPK my_row_id as the first column, every following column gets the metadata of its neighbour and the last one has none, which is the Undefined array key from #19539.

Two ways that I see:

  1. Skip invisible columns at line 2516 and keep a separate index for the result metadata (only counts columns that are in the result).
  2. Select the columns explicitly instead of SELECT * (lines 179 and 265), so invisible columns are in the result, the metadata lines up, and they can be edited in the form like any other column.

Which one would you prefer?

@kamil-tekiela

Copy link
Copy Markdown
Contributor

What do you mean is not enough? I don't understand your reply.

@xmaks82

xmaks82 commented Oct 23, 2026

Copy link
Copy Markdown
Author

Sorry, I'll be more concrete. Take the table from #19539:

CREATE TABLE `user` (
  `my_row_id` bigint unsigned NOT NULL AUTO_INCREMENT INVISIBLE,
  `id` char(36) NOT NULL,
  `created_at` timestamp NOT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`my_row_id`)
);

$tableColumns has 4 entries ($columnNumber 0 to 3), but SELECT * returns only 3 fields, so getFieldsMeta($currentResult) has indexes 0 to 2. For columns without a length in the type (timestamp here), getHtmlForInsertEditFormColumn() does

$column['len'] = $this->dbi->getFieldsMeta($currentResult)[$columnNumber]->length;

For updated_at that is index 3, which does not exist: this is the Undefined array key from the report. If I only add continue for invisible columns at line 2516, my_row_id is skipped, but updated_at still has $columnNumber 3 and still fails (and created_at gets the length of updated_at).

So skipping is fine for the invisible column itself, but the metadata lookup at that line also needs the position of the column in the result, not in the table. Shall I do it that way (skip at 2516 and pass the result position for the metadata), or do you have something else in mind?

Comment thread libraries/classes/InsertEdit.php Outdated
Comment on lines +1929 to +1937
// Invisible columns are not returned by SELECT *, so they cannot be shown in the form
// without shifting the result metadata of the following columns.
return array_values(array_filter(
$this->dbi->getColumns($db, $table, true),
static function (array $column): bool {
return ! isset($column['Extra']) || ! is_string($column['Extra'])
|| stripos($column['Extra'], 'INVISIBLE') === false;
}
));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
// Invisible columns are not returned by SELECT *, so they cannot be shown in the form
// without shifting the result metadata of the following columns.
return array_values(array_filter(
$this->dbi->getColumns($db, $table, true),
static function (array $column): bool {
return ! isset($column['Extra']) || ! is_string($column['Extra'])
|| stripos($column['Extra'], 'INVISIBLE') === false;
}
));
return array_values(array_filter(
$this->dbi->getColumns($db, $table, true),
static function (array $column): bool {
return ! isset($column['Extra']) || ! is_string($column['Extra'])
|| ! str_contains($column['Extra'], 'INVISIBLE');
}
));

@kamil-tekiela

Copy link
Copy Markdown
Contributor

Ok, I understand now. So the only two options are:

  1. Filter invisible columns in getTableColumns()
  2. Refactor the code to build the SQL listing all columns explicitely instead of SELECT * and then, if desirable, skip invisible columns when building the form, but not with in_array which cannot check for combined extra values.

In that case, filtering them out in getTableColumns() is the simplest solution for 5.2.

Signed-off-by: Магда М.Г. <mail@mgmagda.ru>
@xmaks82

xmaks82 commented Oct 24, 2026

Copy link
Copy Markdown
Author

Applied the suggestion (str_contains). Thanks for looking into it.

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.

3 participants