首批通过分布式安全可靠测评,为关键业务系统打造
查询 union 结果集和拆分单独执行 SQL 结果不符合预期
更新时间:2026-05-26 09:46
问题现象
c1,c2 是索引列,当出现条件 (c1 in (xx) or c1 in (yy)) and c2 ... 时,如果 xx,yy 带 cast 导致值变为 ?,且 xx 和 yy 实际值不完全相同 (例如 c1 in ('1','2') or c1 in ('2','3')) and c2 = '0';)时,会出现正确性问题。
关键诊断信息
触发条件
c1,c2 是索引列,当出现条件 (c1 in (xx) or c1 in (yy)) and c2 ... 时,如果 xx,yy 带 cast 导致值变为 ?,且 xx 和 yy 实际值不完全相同(例如 c1 in ('1','2') or c1 in ('2','3')) and c2 = '0';)。
问题原因
在抽取 query range 的 pre 阶段,假设 c1 in 和 c1 in 各自生成的 keypart 做 or 连接,如果两个in keypart 后面都有 c2 生成的 keypart,就会把表达式设为非精确的,从而保证正确性; 但是在这个 case 里,在 pre 阶段的时候还没有 and_next,所以认为是精确的; 在 final 阶段才有 and_next,但是不会再设置非精确了,inkeypart 做完 union 后还是清空了and_next,导致 c2 生成的 range 丢失了,所以结果集不对。
问题的风险及影响
SQL 执行出现正确性问题。
影响租户
影响 OceanBase 数据库中的 Oracle 租户和 MySQL 租户,对于 SYS 租户无影响。
影响版本
OceanBase 数据库 V3.2.3 BP6 Hotfix1()及之后版本、V3.2.4 GA(oceanbase-3.2.4.0-100000072022102819)及之后版本、V4.1.0 GA(oceanbase-4.1.0.0-100001122023040322)及之后版本。
解决方法
该类场景下,保留
c2表达式,使其正常生成range。升级到问题已修复版本,目前已修复的版本包括 OceanBase 数据库 V3.2.3 BP8 Hotfix3(oceanbase-3.2.3.3-108030022023051915)版本、V3.2.3 BP8 Hotfix4(oceanbase-3.2.3.3-108040052023060909)版本、V3.2.3 BP8 Hotfix5(oceanbase-3.2.3.3-108050012023070409)版本、V3.2.3 BP8 Hotfix6(oceanbase-3.2.3.3-108060012023102510)版本、V3.2.3 BP9(oceanbase-3.2.3.3-109000182023071410)及之后版本、V3.2.4 BP4(oceanbase-3.2.4.4-104000052023062021)及之后版本、V4.1.0 BP2(oceanbase-4.1.0.1-102000042023061309)及之后版本。
规避方式
不走含
in条件所在列的索引。将
in条件改成等价的or表达式。