Skip to content

fix(schema): seven CREATE TABLE statements described a table the database never stored (#1087 passo 8) - #1096

Merged
rpgmem merged 1 commit into
developfrom
claude/dbdelta-drift-fixes-4vvuer
Sep 7, 2026
Merged

fix(schema): seven CREATE TABLE statements described a table the database never stored (#1087 passo 8)#1096
rpgmem merged 1 commit into
developfrom
claude/dbdelta-drift-fixes-4vvuer

Conversation

@rpgmem

@rpgmem rpgmem commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Summary

O gate de idempotência do passo 7 mediu 14 declarações que o dbDelta queria alterar contra tabelas que ele mesmo acabara de criar a partir daquelas mesmas declarações. Sete são corrigidas aqui; as outras sete são uma pergunta em aberto, registrada como tal.

  • Display width — 9 declarações, 20 mudanças. As declarações escreviam int unsigned enquanto o MariaDB grava int(10) unsigned. Isto parecia um trade-off entre servidores e não é: o dbDelta do WP core ignora diferença só de width no MySQL 8.0.17+ e explicitamente não no MariaDB (Note: This is specific to MySQL and does not affect MariaDB). Escrever o width está certo nos dois — e é o que o WP core faz no próprio schema. As 3 declarações incrementais que grafavam as mesmas colunas de outro jeito foram alinhadas ao CREATE.
  • ffc_reregistrations.audience_id. A migration ainda declarava coluna e índice que o ReregistrationActivator derruba logo depois, desde que a relação virou tabela de junção: numa instalação nova a coluna nascia e morria na mesma ativação, e a declaração descrevia uma tabela que nunca existe.
  • KEY auth_code em duas tabelas. upgrade_auth_code_unique_constraints() derruba todo índice não-único da coluna e adiciona UNIQUE INDEX uq_auth_code, tanto em ffc_submissions quanto em ffc_reregistration_submissions — o KEY simples que essas declarações traziam nunca sobrevivia. Passam a declarar o UNIQUE que o código realmente cria, mesma forma que o CLAUDE.md já registra para validation_code. Os dois KEY foram adicionados pelos passos 4 e 5 desta mesma issue.

Baseline: 14 declarações / 33 mudanças → 7 / 10.

Deixado em aberto de propósito: json, 7 declarações

O MariaDB implementa JSON como LONGTEXT mais um CHECK, então essas colunas drifta lá para sempre. Declarar longtext limparia o MariaDB e, no MySQL 8, converteria uma coluna json nativa em longtext uma vez — os dados sobrevivem, a validação não. Qual servidor o schema descreve é decisão de produto, não coisa que uma varredura resolve. O dbDelta não oferece saída: suas listas $text_fields/$blob_fields não incluem nenhum dos dois tipos.

Duas correções do que eu afirmei antes

  1. Eu ia registrar que a grafia de inteiro era irreconciliável entre MariaDB e MySQL. O código do dbDelta diz o contrário, e é por isso que esta correção existe.
  2. No comentário do passo 7 eu disse que audience_id era "um ciclo cria/derruba por ativação, indefinidamente". Não écreate_reregistrations_table() tem guarda table_exists(), então numa instalação estabelecida o dbDelta nunca recriava a coluna.

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would alter existing behavior)
  • Refactor / chore (no functional change)
  • Documentation only

Nenhuma instalação existente muda: todos os CREATE TABLE tocados são protegidos por table_exists(), então só uma ativação em banco vazio os executa.

Test plan

  • vendor/bin/phpunit — suíte completa verde (7667 testes, 21980 asserções)
  • vendor/bin/phpunit --filter 'ActivatorSql|SchemaAgreement|CreateStatementsParser' — 11 testes
  • PHPCS nos seis arquivos tocados — limpo
  • PHPStan (nível 8) nos arquivos tocados — sem erros
  • Regra do display width verificada na fonte primária (wp-admin/includes/upgrade.php), não de memória
  • A nova baseline é previsão, não medição. Não há MariaDB neste ambiente. Se eu errei, o job fresh-install falha e imprime o bloco exato para colar.

Checklist

  • Sem mudança de CSS/JS
  • CHANGELOG.md atualizado ([Unreleased]Fixed)
  • CLAUDE.md atualizado — o gate novo e as três lições contra-intuitivas da primeira medição
  • Sem entradas novas de baseline do PHPStan
  • Sem segredos, tokens ou PII no diff

Referencia #1087 (passo 8). A issue segue aberta pelas 7 declarações json e pela consolidação das declarações duplicadas.

🤖 Generated with Claude Code

https://claude.ai/code/session_012XWx9qJdjZdAq8crxM9GCU


Generated by Claude Code

…base never stored (#1087 passo 8)

The idempotence gate measured 14 statements dbDelta wanted to ALTER
against tables it had just created from those very statements. Seven are
fixed here; the remaining seven are one open question, recorded as such.

**Display width — 9 statements, 20 changes.** The statements wrote
`int unsigned` while MariaDB stores `int(10) unsigned`. This looked like
a trade-off between servers and is not: WP core's dbDelta ignores a
width-only difference on MySQL 8.0.17+ and *explicitly not* on MariaDB
("Note: This is specific to MySQL and does not affect MariaDB"), so
writing the width is correct on both — and is what WP core writes in its
own schema. The three incremental ALTERs that spelled the same columns
differently are aligned with the CREATE.

**`ffc_reregistrations.audience_id`.** The migration still declared a
column and index that `ReregistrationActivator` drops right after, having
moved the relationship to a junction table: on a fresh install the column
was created and destroyed in the same activation, and the declaration
described a table that never exists. Correcting the record from the issue
comment: this was NOT a per-activation cycle, because
`create_reregistrations_table()` is guarded by `table_exists()`.

**`KEY auth_code` on two tables.** `upgrade_auth_code_unique_constraints()`
drops every non-unique index on the column and adds `UNIQUE INDEX
uq_auth_code`, on `ffc_submissions` and `ffc_reregistration_submissions`
alike, so the plain KEY these statements declared never survived. They
now declare the UNIQUE the code actually creates — the same shape as
`validation_code` in the self-scheduling tables. Both plain KEYs were
added by passo 4 and passo 5 of this same issue.

**Left open on purpose: `json`, 7 statements.** MariaDB implements JSON
as LONGTEXT plus a CHECK, so those columns drift there forever; declaring
`longtext` would fix MariaDB and, on MySQL 8, convert a native `json`
column once — data survives, validation does not. Which server the schema
describes is a product decision, not something a scan settles. dbDelta
offers no relief: its `$text_fields`/`$blob_fields` leniency lists
neither type.

The baseline shrinks from 14 statements / 33 changes to 7 / 10. That
prediction is not measured — there is no MariaDB in the dev container —
so if it is wrong the gate fails and prints the exact block to paste.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012XWx9qJdjZdAq8crxM9GCU
@rpgmem
rpgmem marked this pull request as ready for review September 7, 2026 03:36
@rpgmem
rpgmem enabled auto-merge (squash) September 7, 2026 03:37
@rpgmem
rpgmem merged commit ac3c9f5 into develop Sep 7, 2026
20 checks passed
@rpgmem
rpgmem deleted the claude/dbdelta-drift-fixes-4vvuer branch September 7, 2026 03:44
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 34079836679

Warning

Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes.
Quick fix: rebase this PR. Learn more →

Warning

No base build found for commit bf43297 on develop.
Coverage changes can't be calculated without a base build.
If a base build is processing, this comment will update automatically when it completes.

Coverage: 89.969%

Details

  • Patch coverage: 3 of 3 lines across 1 file are fully covered (100%).

Uncovered Changes

No uncovered changes found.

Coverage Regressions

Requires a base build to compare against. How to fix this →


Coverage Stats

Coverage Status
Relevant Lines: 53944
Covered Lines: 48533
Line Coverage: 89.97%
Coverage Strength: 4.87 hits per line

💛 - Coveralls

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