fix(db): MySQL 结果列字符集未知时按 UTF-8 兜底解码,修复文本列显示为二进制 - #267
Merged
Merged
Conversation
现象:连接某些 MySQL 兼容实现/代理时,结果列元数据里的 character_set 为 0 (collation_id=0、charset=unknown),decode_character 在取不到 decoder 时一律降级为 DbValue::Binary,文本列因此在网格里显示成「二进制 · N B」;表结构元数据、自定义 SQL 与 UNION ALL 结果不走 schema 纠偏,同样受影响,而字节本身是合法 UTF-8。 修复:字符集未知(collation 0 / 未映射)时用严格 UTF-8 兜底解码,与 decode_untyped_bytes 对无类型字节的判定保持一致(合法 UTF-8 且无控制字符)。 非法 UTF-8 或含控制字符的字节仍保留二进制 sidecar;wire 已声明 collation 63 的字节列仍走 wire-binary 分支;已声明字符集的列行为不变。 取舍:字符集未知的服务端上,内容是「可打印 ASCII」的真二进制列会显示为文本;这类字节此前 显示为二进制,属显示层面的取舍,若需严格区分可按 BINARY_FLAG 收窄。 验证:真机 MySQL 8.0.45 + 把列定义包 character_set 改写成 0 的透明代理复刻现场,表数据 / UNION ALL / information_schema 三条路径的文本列均不再进入 binary_cells,X'000102FF' 这类真 二进制仍为二进制;cargo test -p db --lib 1311 passed(含 3 个新增 codec 回归测试); clippy 对本文件无告警。
feigeCode
force-pushed
the
fix/mysql-unknown-result-charset
branch
from
September 21, 2026 08:36
2cc0bbb to
d46a38d
Compare
4 tasks
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.
现象
连接某些 MySQL 兼容实现 / 中间代理时,结果网格把文本列显示成「二进制 · N B」:表结构、自定义 SQL 都会出现,
UNION ALL这类把字符串字面量和表列混在一起的查询尤其明显。根因
collation_id = 0、charset = unknown(正常 MySQL 给 255/45,character_set_results=binary时给 63)。crates/db/src/mysql/codec.rs的decode_character在column_text_decoder取不到 decoder 时一律降级为DbValue::Binary,网格于是显示二进制 + hex。normalize_table_query_result)能救回这类列;但 information_schema 元数据、自定义 SQL、UNION ALL结果不走这条纠偏,仍然显示二进制。修复
字符集未知(collation 0 / 未映射)时按严格 UTF-8 兜底解码,判定复用
decode_untyped_bytes已有的is_valid_utf8_text(合法 UTF-8 且不含控制字符):DbValue::Text改动集中在
crates/db/src/mysql/codec.rs(+71 行,含 3 个回归测试)。验证
真机链路:本机 MySQL 8.0.45 + 一个透明代理(只把列定义包里的 character_set 改写成 0,协议与数据都来自真实 MySQL)复刻现场。
binary_cells,网格显示二进制UNION ALL(字面量列 + 多分支 + 中文 IN 列表,即现场查询形态)/ information_schema 三条路径binary_cells = 0,文本正常;000102FF、FF00这类真二进制仍是二进制cargo test -p db --lib全绿;cargo clippy -p db --all-targets无新增告警取舍
字符集未知的服务端上,内容是「可打印 ASCII」的真二进制列会显示为文本(此前显示二进制)。
X'0102'这类含控制字符的仍按二进制走;若要严格区分,可再按BINARY_FLAG收窄。