Repository navigation
Store MySQL JSON documents as exact text (#1016) - #1161
Merged
Merged
Conversation
MySQL's json type parses doubles into its own binary form, so history, heartbeat details and other JSON documents could come back one ULP off (1.4820142857142857 as ...855). MariaDB, PostgreSQL and SQLite keep the text. MySQL moves to native schema 13: the 75 json columns in 36 tables become LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin with an enforced json_valid check named dw_json_text_<sha256(table NUL column)[..20]>. A fresh bootstrap creates them directly; schema-upgrade from 12 runs one atomic ALTER per table, and a resumed upgrade or takeover accepts each table only in its exact 12 or 13 definition. MariaDB stays at 12 with an unchanged bootstrap checksum; the transition lock picks the version per server. Stored documents keep MySQL's rendering. Real MySQL 8.0.46 and 8.4.13 and MariaDB 10.11 runs pass the qualification suites; 1M history rows (2.65 GB) upgrade in 115 s on MySQL 8.0 with 2 CPUs. Doubles come back bit-exact on MySQL through history, memo, search attributes and heartbeat details. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The MySQL parity harness compares published PHP's physical catalog with native's. projectMysqlJsonText maps exactly native's utf8mb4_bin text column and named json_valid check back to PHP's json definition for each PHP json column; any other difference still fails. A registered JSON default now keeps its key order on MySQL, as on every other backend: MySQL's json column used to sort object keys. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
Author
|
Update: 3.6.0 is released and promoted, so auto-merge is on. CI fixes in this push:
|
rmcdaniel
enabled auto-merge
November 12, 2026 04:19
|
This was referenced Nov 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Fixes #1016. Native 3.7.0 headline. Do not merge before 3.6.0 is tagged (General, 2026-11-12). Auto-merge stays off until then.
MySQL's
jsontype parses doubles into its own binary form, so history, heartbeat details and other JSON documents could come back one ULP off (1.4820142857142857as…855). MariaDB, PostgreSQL and SQLite keep the text.Change (MySQL only, schema 12 → 13)
rust/migrations/mysql/0013_json_text.sql: the 75jsoncolumns in 36 tables becomeLONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_binwith an enforcedjson_validcheck. Check names follow the Compile MySQL JSON text upgrade table plan and required controls #1035 plan:dw_json_text_plus the first 20 hex digits of SHA-256(table NUL column). There is one atomicALTER TABLEper table.schema-upgradefrom 12 runs the ALTERs, and a resumed upgrade or PHP takeover accepts each table only in its exact 12 or 13 definition. The older steps (8–11) now build toward the schema-12 catalog. On real MySQL the fresh and upgraded catalogs are byte-identical.mariadb/0012_checksum.txt). The transition lock selects the version withIF(VERSION() LIKE '%MariaDB%',12,13), the upgrade report carries the target, and takeover marks the flavor's version. MySQL's retained schema-12 checksum is pinned inmysql/0012_checksum.txtand equals main's current one.JSON_EXTRACT/JSON_UNQUOTESQL MariaDB runs on text, and sqlx bindsJsonas a string, so text is stored verbatim.json-doubleskeepsmysql_json_doublesfor published PHP only; native expects exact history on MySQL.General's gates
qualification_json_text_upgrade_timing,DW_JSON_TEXT_TIMING_ROWS): MySQL 8.0.46, 2 CPUs, default 128 MiB buffer pool, 1,000,000 ~1 KiB history rows (2.65 GB data): upgrade 115 s, about 2 min per 1M history rows.doubles_come_back_bit_exact_through_history_memo_search_attributes_and_heartbeatschecksto_bits()equality for the memo (describe andWorkflowStarted), double search attributes (describe, list andWorkflowStarted) and heartbeat details, read through a fresh runtime. On MySQL it also asserts thatworkflow_history_events.payloadislongtext. It passes on SQLite and real MySQL 8.0. The existing memo test now expects exact history on MySQL as well.rust/README.md): MySQL only; stop every node, back up, runschema-upgrade, then start; downtime for the whole upgrade at about 2 min per million history rows; existing rows keep MySQL's rendering; rollback means restoring the backup. The 3.7.0 release notes and chart UPGRADING will repeat it.Tests
qualification_version_12_json_text_upgrade_resumes_and_keeps_rows. It covers an upgrade before any change, resume after two committed tables, refusal of a foreign table definition, a 12-era row keeping MySQL's rendering, 75 enforced checks, new text kept exactly, and invalid JSON refused.php.🤖 Generated with Claude Code