fix(migrations): coerce COUNT result to Number before comparison#415
Conversation
db/config.js sets bigNumberStrings: true for all environments, which
causes mysql2 to return COUNT() values as strings ("0") instead of
numbers (0). Four index-creation migrations used strict equality
(=== 0 / > 0) against that string, so the condition was always false
and the CREATE INDEX statements were silently skipped — migrations
completed and were recorded in SequelizeMeta but created no indexes.
Affected migrations:
- 20251201104138-add-tx-output-utxo-lookup-index
- 20260108100000-add-tx-output-locked-heightlock-index
- 20260108100001-add-tx-output-locked-timelock-index
- 20260108100002-add-address-tx-history-addr-voided-token-index
Fix: wrap the count value with Number() before comparing, so both
string and numeric returns are handled correctly.
Note: databases that already ran these migrations will not get the
indexes automatically (migrations won't re-run). The missing indexes
must be created manually:
CREATE INDEX idx_tx_output_utxo_lookup
ON tx_output (address, token_id, spent_by, voided, locked, authorities);
CREATE INDEX idx_tx_output_locked_heightlock
ON tx_output (locked, heightlock);
CREATE INDEX idx_tx_output_locked_timelock
ON tx_output (locked, timelock);
CREATE INDEX idx_address_tx_history_addr_voided_token
ON address_tx_history (address, voided, token_id);
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughFour database migration files receive type-coercion fixes: index count results from SQL queries are wrapped with ChangesDatabase Index Migration Type Coercion
Estimated code review effort🎯 2 (Simple) | ⏱️ ~5 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
Fixes several MySQL index-creation migrations that were incorrectly skipping CREATE INDEX due to COUNT() values being returned as strings (because mysql2 is configured with bigNumberStrings: true).
Changes:
- Coerce
COUNT()results viaNumber(indexes[0].count)before doing strict numeric comparisons in four migrations. - Ensures
upcreates indexes when missing anddowndrops them when present, regardless of whether the driver returns counts as strings or numbers.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| db/migrations/20251201104138-add-tx-output-utxo-lookup-index.js | Coerces index existence COUNT() to a number before comparing in up/down. |
| db/migrations/20260108100000-add-tx-output-locked-heightlock-index.js | Coerces index existence COUNT() to a number before comparing in up/down. |
| db/migrations/20260108100001-add-tx-output-locked-timelock-index.js | Coerces index existence COUNT() to a number before comparing in up/down. |
| db/migrations/20260108100002-add-address-tx-history-addr-voided-token-index.js | Coerces index existence COUNT() to a number before comparing in up/down. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
db/config.js sets bigNumberStrings: true for all environments, which
causes mysql2 to return COUNT() values as strings ("0") instead of
numbers (0). Four index-creation migrations used strict equality
(=== 0 / > 0) against that string, so the condition was always false
and the CREATE INDEX statements were silently skipped — migrations
completed and were recorded in SequelizeMeta but created no indexes.
Affected migrations:
- 20251201104138-add-tx-output-utxo-lookup-index
- 20260108100000-add-tx-output-locked-heightlock-index
- 20260108100001-add-tx-output-locked-timelock-index
- 20260108100002-add-address-tx-history-addr-voided-token-index
Fix: wrap the count value with Number() before comparing, so both
string and numeric returns are handled correctly.
Note: databases that already ran these migrations will not get the
indexes automatically (migrations won't re-run). The missing indexes
must be created manually:
CREATE INDEX idx_tx_output_utxo_lookup
ON tx_output (address, token_id, spent_by, voided, locked, authorities);
CREATE INDEX idx_tx_output_locked_heightlock
ON tx_output (locked, heightlock);
CREATE INDEX idx_tx_output_locked_timelock
ON tx_output (locked, timelock);
CREATE INDEX idx_address_tx_history_addr_voided_token
ON address_tx_history (address, voided, token_id);
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
db/config.jssetsbigNumberStrings: truefor all environments, causing mysql2 to returnCOUNT()values as strings ("0") instead of JavaScript numbers (0)=== 0/> 0) against that string value —"0" === 0isfalsein JS, so theCREATE INDEXblock was always skippedSequelizeMeta, but the indexes were never actually createdAffected migrations
20251201104138-add-tx-output-utxo-lookup-indexidx_tx_output_utxo_lookup20260108100000-add-tx-output-locked-heightlock-indexidx_tx_output_locked_heightlock20260108100001-add-tx-output-locked-timelock-indexidx_tx_output_locked_timelock20260108100002-add-address-tx-history-addr-voided-token-indexidx_address_tx_history_addr_voided_tokenFix
Wrap the
COUNT()result withNumber()before comparing, so both string and numeric returns work correctly:Manual remediation required for existing databases
Since these migrations have already run and won't execute again, the missing indexes must be created manually on any affected database (staging, production, etc.):
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit