Skip to content

fix(mysql): run the installed command, dedupe by instant, refuse out-of-range offsets - #50

Merged
gjtorikian merged 3 commits into
mainfrom
fix/mysql-cli-dedupe-offsets
Nov 5, 2026
Merged

gjtorikian merged 3 commits into
mainfrom
fix/mysql-cli-dedupe-offsets

Conversation

@gjtorikian

@gjtorikian gjtorikian commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Three bugs Greptile found in the MongoDB destination (#41) that sync-mysql shares, each with a test:

  • The installed command did nothing. The entrypoint check compared process.argv[1] against cli.js, but npm installs a bin as a symlink named workos-sync-mysql, so npx workos-sync-mysql imported main() and exited. invokedDirectly() now resolves both the argv path and the module URL to real paths before comparing. The Docker image was unaffected, since it runs node dist/cli.js directly.
  • dedupeByKey compared timestamps as text, so a batch mixing offset and UTC forms (01:00:00+01:00 vs 00:30:00Z) could keep the older row on the delete, relink and unlink paths. It now orders by the instant at the precision a DATETIME(6) keeps (Date.parse reads only three fractional digits), falling back to text for a value that is not a date, which the database refuses on the write anyway.
  • The timestamp expression accepted out-of-range offsets such as +00:99 and applied them as 99 minutes. The offset's hours and minutes are now range-checked like the clock's. This changes the generated column DDL the package records in _columns, which would read as drift on an existing deployment; nothing has shipped, so there is none.

Two findings Greptile raised on the MongoDB destination that this
package shares:

- The entrypoint check compared `process.argv[1]` against `cli.js`, but
  npm installs the `bin` as a symlink named `workos-sync-mysql`, so the
  installed command imported `main()` and exited. Both sides are now
  resolved to real paths and compared.
- `dedupeByKey` compared `updatedAt` as text, so a batch mixing offset and
  UTC forms could keep the older row. It now orders by the instant, and
  falls back to text for a value that is not a date, which the database
  refuses on the write anyway.
@greptile-apps

greptile-apps Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge.

Summary

The PR fixes the installed MySQL command and timestamp comparisons.

  • The installed MySQL command now starts the sync CLI.
  • MySQL cleanup keeps the row with the newest timestamp instant.
  • MySQL timestamp columns turn invalid timezone offsets into NULL.

No new actionable issues were found in the changes since the previous review. gjtorikian acknowledged the changed DDL and stated that nothing has shipped.

Reviews (3) · Last reviewed commit: "fix(mysql): refuse an out-of-range offse..." · Reviewed by Greptile

Date.parse reads three fractional digits and a DATETIME(6) keeps six, so
two removals a microsecond apart tied and the later row in the batch won,
whichever was newer. The rest of the fraction is read alongside it now.
The generated column range-checked the clock but not the offset, so
`+00:99` was accepted and applied as 99 minutes. The offset's hours and
minutes are now checked like the clock's. Nothing has shipped, so no
recorded column DDL changes under a live deployment.
@gjtorikian gjtorikian changed the title fix(mysql): run the installed command, dedupe by instant fix(mysql): run the installed command, dedupe by instant, refuse out-of-range offsets Nov 5, 2026
@gjtorikian
gjtorikian merged commit 05e8fb4 into main Nov 5, 2026
16 checks passed
gjtorikian added a commit that referenced this pull request Nov 5, 2026
… out-of-range offsets

The same three fixes Postgres (#49) and MySQL (#50) got. npm installs the
bin as a symlink named after the command, which the old argv check did
not recognise, so `npx workos-sync-clickhouse` imported the CLI and did
nothing. Duplicate keys in a batch are now judged by the instant each
timestamp names rather than by its text, so `01:00:00+01:00` no longer
outranks `00:30:00Z`. And the timestamp projection range-checks the
clock and the offset ahead of the best-effort parser, which read
`24:00` as the next midnight and `+00:99` as a zone where the other
destinations project NULL.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant