Skip to content

Fix a warning for a foreign key referencing a table with a shorter unique key - #523

Merged
JanJakes merged 1 commit into
WordPress:trunkfrom
Nandan108:fix/composite-foreign-key-shorter-unique-index
Oct 13, 2026
Merged

JanJakes merged 1 commit into
WordPress:trunkfrom
Nandan108:fix/composite-foreign-key-shorter-unique-index

Conversation

@Nandan108

@Nandan108 Nandan108 commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Creating a multi-column foreign key raises Undefined array key 1 warnings when the referenced table also has a unique key with fewer columns:

CREATE TABLE p (a INT NOT NULL, b INT NOT NULL, UNIQUE KEY ua (a), UNIQUE KEY uab (a, b));
CREATE TABLE c (a INT NOT NULL, b INT NOT NULL, FOREIGN KEY (a, b) REFERENCES p (a, b));
-- Warning: Undefined array key 1 in class-wp-sqlite-information-schema-builder.php

When looking for the unique constraint a foreign key references, each unique index of the referenced table is checked for having the referenced columns as a prefix. A shorter index is read past its end. The resulting UNIQUE_CONSTRAINT_NAME is still correct, but the warning is emitted, and under WP_DEBUG it is printed into the page.

Fix

Indexes with fewer columns than the reference are skipped, since they cannot have the referenced columns as a prefix.

Tests

testInformationSchemaForeignKeysReferencingShorterUniqueKey checks that the statement succeeds without a warning and that REFERENTIAL_CONSTRAINTS.UNIQUE_CONSTRAINT_NAME is the longer key. It fails on trunk with the warning (PHPUnit converts warnings to exceptions).

packages/mysql-on-sqlite: 1044 tests pass (PHP 8.3, SQLite 3.45.1); PHPCS is clean.

Found while running WooCommerce on WordPress Playground.

Use of AI

This change was prepared with Claude Code (Claude Fable 5.1). I reviewed the code, the tests, and this description, and I take responsibility for the change.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Corrected foreign-key metadata to report the unique constraint that matches the referenced columns when multiple unique constraints exist. This prevents a shorter, non-matching constraint from being selected and improves the accuracy of constraint information exposed by the database.

…ique key

When looking for the unique constraint that a foreign key references, each
unique index of the referenced table is checked for having the referenced
columns as a prefix. An index with fewer columns than the foreign key was
read past its end, raising "Undefined array key" warnings.

Skip indexes that are shorter than the column list of the reference.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: e707ff5e-6eb0-4fec-a0f1-f7b79a309371

📥 Commits

Reviewing files that changed from the base of the PR and between 6546e45 and 1b3e935.


📒 Files selected for processing (2)
  • packages/mysql-on-sqlite/src/sqlite/class-wp-sqlite-information-schema-builder.php
  • packages/mysql-on-sqlite/tests/WP_MySQL_On_SQLite_Metadata_Tests.php

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 0 remain after this review.



📝 Walkthrough

Walkthrough

The information-schema builder now skips candidate unique indexes that have fewer columns than a foreign key references. A test checks that a two-column foreign key resolves to the matching composite unique key.

Changes

Foreign key metadata

Layer / File(s) Summary
Filter candidate unique keys
packages/mysql-on-sqlite/src/sqlite/class-wp-sqlite-information-schema-builder.php, packages/mysql-on-sqlite/tests/WP_MySQL_On_SQLite_Metadata_Tests.php
The builder skips candidate indexes that are shorter than the referenced-column list. A test checks that the foreign key resolves to the matching composite unique key.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: janjakes


Merge Risk: ⚪ Minimal · up to 1b3e9

The change addresses the shorter-index warning while preserving selection of the matching composite key. No actionable merge risk remains from the inspected changes.

Pre-merge checks | Passed 4 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly identifies the main change: fixing a warning caused by a foreign key referencing a shorter unique key. It is specific and concise.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

🔧 PHPStan (2.2.14)

PHPStan reported 1 non-file analysis error(s); analysis is incomplete



Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@JanJakes JanJakes 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.

Thanks for the fix!

@JanJakes
JanJakes merged commit 5deb4d6 into WordPress:trunk Oct 13, 2026
24 checks passed
JanJakes added a commit that referenced this pull request Oct 14, 2026
… case (#534)

## Summary

Follow-up to #523.

When a foreign key references columns with a different letter case than
the referenced table declares them, the referenced unique constraint is
not found:

```sql
CREATE TABLE t1 (id INT, name VARCHAR(255), PRIMARY KEY (id, name));
CREATE TABLE t2 (id INT, name VARCHAR(255), FOREIGN KEY (id, name) REFERENCES t1 (ID, Name));
SELECT unique_constraint_name FROM information_schema.referential_constraints WHERE table_name = 't2';
-- NULL   (MySQL: PRIMARY)
```

MySQL column names are case-insensitive, but the lookup compared the
referenced column names to the index columns with `!==`. The foreign key
itself works, since SQLite also matches column names case-insensitively;
only the information schema entry is wrong.

## Fix

The names are compared case-insensitively with `strcasecmp()`, which
compares them directly, without creating lowercased copies first.
Identifiers are restricted to ASCII in this driver, so this is
sufficient.

## Tests


`testInformationSchemaForeignKeysReferencingColumnsInDifferentLetterCase`
references a single-column primary key, a composite unique key, and a
unique key in a foreign key added with `ALTER TABLE`, all with
differently cased column names, and checks `UNIQUE_CONSTRAINT_NAME`. It
fails on `trunk` with `NULL` for all three.

## Use of AI

This change was prepared with Claude Code (Claude Fable 5.1). I reviewed
the code, the tests, and this description, and I take responsibility for
the change.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Foreign-key metadata now correctly matches referenced columns when
their names use different letter casing. This applies to single-column
and composite references, whether constraints are defined during table
creation or added afterward.
* Information schema results now identify the expected unique indexes
for these foreign-key references, including primary-key references.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Jan Jakeš <jan@jakes.pro>
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.

2 participants