Skip to content

feat(schema): SchemaDiffer に add-index path を追加する (#421, FT17 F-5)#424

Merged
hideyukiMORI merged 1 commit into
mainfrom
feat/421-schema-diff-add-index
May 22, 2026
Merged

feat(schema): SchemaDiffer に add-index path を追加する (#421, FT17 F-5)#424
hideyukiMORI merged 1 commit into
mainfrom
feat/421-schema-diff-add-index

Conversation

@hideyukiMORI
Copy link
Copy Markdown
Owner

FT17 (#417) で deferred とした最後の ADR-0009 initial-scope 項目 (Add index) を消化。

SchemaDiffer

  • `diff()` 戻り値に `newIndexes` を追加
  • `inSync` flag が newTables / newColumns / newIndexes 全部空時のみ true
  • 既存 live のみの index → warning (drop must be hand-written)
  • `createIndexSql()` は MySQL / SQLite 共通 syntax 出力

CLI 拡張

  • MySQL: `INFORMATION_SCHEMA.STATISTICS` で index 列挙、PRIMARY と UNIQUE (NON_UNIQUE=0) を除外
  • SQLite: `PRAGMA index_list` + `PRAGMA index_info`、`sqlite_autoindex_*` と UNIQUE (unique=1) を除外
  • stdout 出力に "new index" section 追加

Hidden bug 解消

UNIQUE filter なしのとき、CREATE TABLE の `unique` 由来 index (`users_user_id_unique`) が "live にあるが SchemaDefinition の indexes に無い" と誤検出 → false warning を毎回出していた。UNIQUE filter で解消。

Live verification

  • 既存 schema: in-sync (UNIQUE false-positive 解消確認)
  • DROP INDEX → CLI が `CREATE INDEX todos_user_id_index ON todos (user_id);` を emit
  • pipe back → in-sync

Tests (+4, 142/142)

`SchemaDifferTest`:

  • testNewIndexEmitsCreateIndex
  • testCompositeIndexEmitsBothColumns
  • testExtraLiveIndexEmitsWarningNotSql
  • testIndexInSyncDoesNotEmitDuplicate

ADR-0009 scope 完了

initial scope (Add column / Add table / Add index) 全揃い。Closes #421.

Test plan

  • composer test 142/142 (138 → 142)
  • composer analyze (Phan) exit 0
  • composer format:check exit 0
  • live: DROP INDEX → CREATE INDEX emit + apply → in-sync

Closes #421.

FT17 (#417) で deferred とした最後の ADR-0009 scope 項目を消化。
SchemaDefinition の indexes キーに新規追加した index を cli/schemaDiff.php
が "CREATE INDEX" として emit するように。

### SchemaDiffer

- diff() 戻り値に newIndexes 追加 (newColumns と同 shape)
- inSync は newTables + newColumns + newIndexes 全部空のとき true
- 既存 live のみの index → warning (drop must be hand-written)
- createIndexSql() は MySQL / SQLite 共通 syntax (両 driver で動く)

### CLI 拡張

- introspectMysql に INFORMATION_SCHEMA.STATISTICS index 列挙を追加
  - PRIMARY 除外 + NON_UNIQUE=1 フィルタ
  - UNIQUE constraint 由来 index は \`unique\` キー管理なので除外
- introspectSqlite に PRAGMA index_list + PRAGMA index_info を追加
  - sqlite_autoindex_* 除外 + unique=1 除外 (同じ理由)
- stdout 出力に "new index: <name> on <table>" + CREATE INDEX SQL

### Tests (4 cases追加 → 142/142)

- testNewIndexEmitsCreateIndex
- testCompositeIndexEmitsBothColumns (multi-column index)
- testExtraLiveIndexEmitsWarningNotSql
- testIndexInSyncDoesNotEmitDuplicate

### Live verification

- 既存 schema: in-sync (UNIQUE false-positive 解消、これは UNIQUE filter
  が無いと users_user_id_unique を誤検出していた hidden bug)
- DROP INDEX todos_user_id_index 後の diff → CREATE INDEX 出力
- 出力を mysql に pipe → 復元 → in-sync

### ADR-0009 scope 完了

ADR-0009 が当初指定した initial scope (Add column / Add table /
**Add index**) が本 PR で揃った。残るは drop / type-change / rename /
constraint changes — それらは ADR の destructive-op rule で warning-only
扱い、operator hand-write。

Closes #421.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hideyukiMORI hideyukiMORI merged commit e79f62b into main May 22, 2026
2 checks passed
@hideyukiMORI hideyukiMORI deleted the feat/421-schema-diff-add-index branch May 22, 2026 17:07
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.

FT17 follow-up (F-5): SchemaDiffer に add-index path を追加する

1 participant