Skip to content

Fix schema reconstruction with native numeric results - #506

Merged
JanJakes merged 1 commit into
trunkfrom
reconstruction-fetch-flags
Sep 10, 2026
Merged

JanJakes merged 1 commit into
trunkfrom
reconstruction-fetch-flags

Conversation

@JanJakes

@JanJakes JanJakes commented Sep 9, 2026 •

Copy link
Copy Markdown
Member

Summary

Make schema reconstruction independent of PDO::ATTR_STRINGIFY_FETCHES. Interpret SQLite's primary-key, nullability, and uniqueness flags as integers so reconstruction preserves auto-increment columns, NOT NULL, defaults, and unique indexes in either fetch mode.

Add a regression test that creates an existing SQLite table before driver initialization and verifies its reconstructed column and index metadata with string fetching enabled and disabled.

Why

Reconstruction compared SQLite's numeric flags strictly against strings. Since connection initialization stopped forcing string results in #291, reconstruction can receive integers before WordPress enables string fetching. This could mark every column in an auto-increment table as auto-incrementing, causing a later ALTER TABLE to fail with "has more than one primary key."

Related to #422.

Summary by CodeRabbit

  • Bug Fixes

    • Improved compatibility when SQLite returns column and index metadata as either strings or integers.
    • Information schema reconstruction now consistently handles numeric metadata values regardless of fetch settings or PHP version.
    • Schema and index details are reconstructed more reliably across different SQLite metadata formats.
  • Tests

    • Added coverage for schema reconstruction with stringified and native SQLite fetch values.
    • Verified reconstructed column metadata and index statistics across supported configurations.

@coderabbitai

coderabbitai Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

Review Change StackReview 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: eade14f6-c3af-409d-99e1-ec3fd342dd5f

📥 Commits

Reviewing files that changed from the base of the PR and between 743439f and 71c946c.

📒 Files selected for processing (1)
  • packages/mysql-on-sqlite/tests/WP_SQLite_Information_Schema_Reconstructor_Tests.php

Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review.


📝 Walkthrough

Walkthrough

The information schema reconstructor now casts SQLite metadata flags to integers before comparison. Parameterized tests verify reconstruction with native and stringified PDO fetch values.

Changes

SQLite metadata normalization

Layer / File(s) Summary
Normalize metadata flag comparisons
packages/mysql-on-sqlite/src/sqlite/class-wp-sqlite-information-schema-reconstructor.php
The reconstructor casts notnull, pk, and unique metadata values to integers before comparison.
Validate stringified fetches
packages/mysql-on-sqlite/tests/WP_SQLite_Information_Schema_Reconstructor_Tests.php
Parameterized tests cover native and stringified PDO fetch values and verify reconstructed column and index metadata.

Priority: ➖ Normal

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

Merge Risk: ⚪ Minimal · up to 71c94

Schema reconstruction now preserves SQLite column and index metadata regardless of PDO numeric fetch representation. The change includes coverage for both stringified and native numeric results, with no remaining merge-blocking risk identified.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 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 and concisely describes the main change: making schema reconstruction work with native numeric SQLite results.
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 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch reconstruction-fetch-flags

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 force-pushed the reconstruction-fetch-flags branch 2 times, most recently from 6068950 to 743439f Compare September 9, 2026 14:18
@JanJakes
JanJakes marked this pull request as ready for review September 9, 2026 14:19
Normalize SQLite’s numeric schema flags before strict comparisons.
Cover reconstruction with string fetching enabled and disabled,
including column defaults, nullability, and indexes.

#422
@JanJakes
JanJakes force-pushed the reconstruction-fetch-flags branch from 743439f to 71c946c Compare September 9, 2026 16:14
@JanJakes

Copy link
Copy Markdown
Member Author

This is a straightforward fix. I'll go ahead and merge this one.

@JanJakes
JanJakes merged commit 61f246f into trunk Sep 10, 2026
25 checks passed
@JanJakes
JanJakes deleted the reconstruction-fetch-flags branch September 10, 2026 07:02
@JanJakes JanJakes mentioned this pull request Sep 10, 2026
JanJakes added a commit that referenced this pull request Sep 10, 2026
## Release `3.0.2`

Version bump and changelog update for release `3.0.2`.

**Changelog draft:**
* Fix schema reconstruction with native numeric results
([#506](#506))
* Fix lexer edge cases and string handling
([#505](#505))
* Preserve index prefix lengths and order in SHOW CREATE TABLE primary
keys
([#500](#500))
* Align savepoint handling with MySQL semantics
([#496](#496))

**Full changelog:**
v3.0.1...release/v3.0.2

## Next steps

1. **Review** the changes in this pull request.
2. **Push** any additional edits to this branch (`release/v3.0.2`).
3. **Merge** this pull request to complete the release.

Merging will automatically build the plugin ZIP, create a [GitHub
release](https://github.com/WordPress/sqlite-database-integration/releases),
and deploy to
[WordPress.org](https://wordpress.org/plugins/sqlite-database-integration/).

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

- **Bug Fixes**
  - Improved schema reconstruction when handling native numeric results.
  - Corrected lexer edge cases and string processing.
- Fixed index prefix lengths and ordering in `SHOW CREATE TABLE` output
for primary keys.
  - Improved savepoint handling to better match MySQL behavior.

- **Release**
  - Updated the SQLite integration to version 3.0.2.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
batonac added a commit to Avunu/sqlite-database-integration that referenced this pull request Sep 11, 2026
Brings in upstream's Release 3.0.2 and the schema-reconstruction fix (WordPress#506).
The only conflicts were the plugin header, where the release bumped the version
and this branch raised the PHP floor: both survive -- Version 3.0.2,
Requires PHP 8.0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
JanJakes added a commit that referenced this pull request Oct 14, 2026
…532)

## Summary

Fixes #451 together with #522.

`ALTER TABLE`, `CREATE TABLE`, and `SHOW CREATE TABLE` compare fetched
metadata to string values. PDO SQLite returns native types unless
`PDO::ATTR_STRINGIFY_FETCHES` is set, so on PHP 8.1 and newer, these
comparisons fail for callers that don't set that attribute. The
WordPress plugin and the MySQL proxy set it, so they are unaffected, but
the PDO-compatible API is:

```php
$pdo = new WP_MySQL_On_SQLite( 'mysql-on-sqlite:dbname=wp', ... );
$pdo->query( 'CREATE TABLE u (id INT, email VARCHAR(50), UNIQUE KEY ue (email))' );
$pdo->query( "INSERT INTO u VALUES (1, 'a@example.com')" );
$pdo->query( "INSERT INTO u VALUES (2, 'a@example.com')" );
// Accepted: the unique key was created as a plain index.
```

The affected comparisons are the remaining ones listed in #451:

- `NON_UNIQUE` is compared to `'0'` when generating the SQLite schema
and when generating `SHOW CREATE TABLE` output, so every `UNIQUE KEY`
becomes a plain index. That also breaks `INSERT ... ON DUPLICATE KEY
UPDATE`, which then inserts duplicates.
- `PRAGMA foreign_keys` is compared to `'1'` after `ALTER TABLE`
recreates a table, so the foreign key check is skipped.

#522 fixes the temporary table lookup, and #506 already fixed schema
reconstruction.

## Fix

The values are compared as integers.

## Tests

`testUniqueKeysWithoutStringifiedFetches` disables stringified fetches,
creates a table with a unique key, checks `SHOW CREATE TABLE`, recreates
the table with `ALTER TABLE`, and checks that a duplicate row is
rejected. It fails on `trunk`. Each of the two `NON_UNIQUE` comparisons
fails it separately.

The `PRAGMA foreign_keys` comparison has no test. `ALTER TABLE` runs
inside the wrapper transaction, where `PRAGMA foreign_keys` is a no-op,
so the skipped restore has no observable effect today. It is fixed for
consistency.

I also ran the whole suite with stringified fetches disabled in every
test class. With this PR and #522, the only remaining failures are type
differences in returned values (`1` vs `'1'`) and the two tests of the
attribute itself.

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

## Use of AI

This change was prepared with Claude Code (Claude Opus 5.5). 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**
- Fixed unique database indexes being lost when tables are recreated
after a schema change. Duplicate values in uniquely constrained fields
are now correctly rejected.
- Improved consistency when adding columns to tables: unique constraints
are preserved whether database results are returned as strings or other
value types. Database table definitions also continue to report unique
indexes correctly in either case.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 5.5 <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.

1 participant