已关闭
[Bug]: dolphin prepared 参数类型未剥离高位标志导致 SeaORM BOOLEAN 存为 NULL #1631
Rourou2285创建于  25 天前关闭于  17 天前
Rourou2285
Rourou2285
25 天前 创建

问题描述

使用 SeaORM(底层为 SQLx 0.8 MySQL 驱动)通过 prepared statement 插入 BOOLEAN 字段并绑定 true 时,落库结果为 NULL,而非 true。

复现方式

use sea_orm::{ActiveModelTrait, Set};

let st = sea_type::ActiveModel {
    bool_val: Set(true),
    ..Default::default()
};
st.insert(db).await?;
// 读取后 loaded.bool_val == None(NULL),期望为 true

SeaORM 将 bool 绑定为参数类型 TINY,并声明 UNSIGNED 标志,因此 16 位参数类型字段为 0x8001(低字节 = 类型 TINY=1,高字节 = flag 0x80)。

根因

COM_STMT_EXECUTE 参数类型字段按协议为 16 位:低 8 位是类型,高 8 位是标志(UNSIGNED/BINARY/BLOB 等)。dolphin 的 make_stmt_parameters_bytype() 用完整 16 位值直接和 DOLPHIN_TYPE_* 常量比较,导致高字节标志使比较失败,参数类型分派落入 default(参数 type 保持初始值 0),值未被正确解析,最终存为 NULL。

修复

contrib/dolphin/plugin_protocol/dqformat.cpp 的 make_stmt_parameters_bytype():

- switch (stmt_param->itypes[i]) {
+ switch (stmt_param->itypes[i] & 0xff) {

只比较低 8 位类型,正确忽略高 8 位标志。对所有 DOLPHIN_TYPE_*(1~255,均 ≤255)无损;同时修复带 UNSIGNED 标志的整数等参数。

验证

  • 修复前:BOOLEAN 绑定 true 存储为 NULL。
  • 修复后:bool roundtrip = true;decimal/datetime/json/blob/null 类型 roundtrip 全部通过。

结论

原实现未剥离参数类型字段的高位标志即参与比较,属协议边界错误(正确性缺陷),对无标志参数无影响,对带标志参数(含 bool)修复。

关联 MR:基于 seaorm-fix-prep-mask 分支提交。

likedislike
opengauss_bot
opengauss_bot成员
25 天前 评论:

This issue requires an assignee. Since you haven't specified one, we've assigned TestManager as the default assignee for this issue.

likedislike
opengauss_botopengauss_bot成员
25 天前 将 TestManager 设为负责人
opengauss_botopengauss_bot成员
25 天前 添加了label:sig/Plugin
opengauss_bot
opengauss_bot成员
25 天前 评论:

Welcome To openGauss Community

Hey @Rourou2285 , thanks for your contribution to the community.

Bot Usage Manual

I'm the Bot here serving you. You can find the instructions on how to interact with me at Here . That means you can comment below every pull request or issue to trigger Bot Commands. You can self-configure the PR merge rules for this repository. For more details, please refer to Here.

Contact Guide

If you have any questions, please contact the SIG: Plugin ,
and any of the maintainers: @CarrotGo, @chendong76, @chenxiaobin19, @congzhou2603, @dodders, @hwworkholic, @jemappellehc, @libiao2024, @muyulinzhong, @quemingjian, @shenzheng4, @shirley_zhengx, @superlchf, @totaj, @wlff234, @wofanzheng, @ywzq1161327784 ,
and any of the committers: @dreamalloc, @huyinghao, @libiao2024, @wangfeihuo, @wmy_ld, @wuyuechuan, @xiong_xjun, @zhangxubo, @zhaojunv3z810 .

likedislike
Rourou2285Rourou2285
25 天前 关联了pull request:[dolphin] SeaORM: 修复 prepared 参数类型未剥离高位标志导致 BOOLEAN 存为 NULL
liuzhen001liuzhen001成员
22 天前 关联了看板:openGauss 7.0.0-LTS
ywzq1161327784ywzq1161327784成员
21 天前 移除了负责人 TestManager
opengauss_bot
opengauss_bot成员
21 天前 评论:

This issue requires an assignee. Since you haven't specified one, we've assigned TestManager as the default assignee for this issue.

likedislike
opengauss_botopengauss_bot成员
21 天前 将 TestManager 设为负责人
ywzq1161327784ywzq1161327784成员
21 天前 将 superlchf 设为负责人,移除负责人 TestManager
Rourou2285Rourou2285
21 天前 关联了pull request:[实习#45] SeaORM 兼容性测试工程(含 #1630/#1631 测试用例)
Rourou2285Rourou2285
20 天前 关联了pull request:【回合 7.0.0】dolphin MySQL 协议修复回合(出站>16MB 分包 / OK·EOF 事务标志 / prepared 参数剥离高位标志)
Rourou2285
Rourou2285
19 天前 评论:

验证结果:通过(PASS)

测例:SeaORM param_flags 模块(examples 测例链接 https://atomgit.com/opengauss/examples/merge_requests/115)

用例 覆盖 结果
PF1 BOOLEAN 绑定 true → 1 PASS
PF2 BOOLEAN 绑定 false → 0 PASS
PF3 BIGINT/INT/SMALLINT/TINYINT UNSIGNED 最大值 PASS
PF4 signed INT 参数对照 PASS
PF6 WHERE 中的无符号参数 PASS
PF7 标志不变性:同值带/不带 UNSIGNED 标志绑定结果相等 PASS
PF8 无符号零值(带标志的 0 不为 NULL) PASS
PF9 带标志参数的 NULL PASS
PF10 带标志参数出现在 UPDATE SET / WHERE PASS
PF11 同一语句混用不同宽度的带标志参数 PASS
PF12 BOOLEAN 参数出现在 WHERE 谓词中 PASS

(PF5 为 BLOB 参数往返,属另一独立问题,与本 issue 无关。)

likedislike
Ssuperlchf成员
19 天前 issue状态由 待办的 改变为 待回归
Ssuperlchf成员
19 天前 issue状态由 待回归 改变为 已完成
Ssuperlchf成员
19 天前 issue状态由 已完成 改变为 待回归
superlchf成员
17 天前 评论:

单独按照issue构建测试用例,pass
image.png
使用测试用例:SeaORM param_flags 模块,11个通过,其中PF5非该issue,符合描述预期
image.png

likedislike
ywzq1161327784ywzq1161327784成员
17 天前 issue状态由 待回归 改变为 已验收
ywzq1161327784ywzq1161327784成员
17 天前 关闭了 issue