matrixorigin / matrixorigin/matrixone

[Bug]: Prepared binary-string bitwise operators ignore setBytes byte semantics

Open
#28,791 3 comments 0 reactions 1 assignee Claimed by @XuPeng-SH View on GitHub
kind/bug needs-triage
Dominant language
Go
Stars
1.9k
Forks
311
Avg merge
1d 3h
Merged PRs (30d)
768

Description

## 问题描述

二进制协议 PreparedStatement 绑定 `setBytes()` 参数后,二进制位运算没有保留 binary-string domain,而是落入数值语义。等长字节串返回错误的数值结果;不等长字节串没有执行 MySQL 要求的长度校验。

字面量 `_binary X'...'` 和表列的等长二进制运算已能走字节语义,因此该问题集中在 binary-protocol 参数绑定/运行时特化路径。

## 环境

- MatrixOne: `main@6875e4203519de1ed98b842c1cbc8c57f11dc326`
- Connector/J 8.4.0,`useServerPrepStmts=true`,`cachePrepStmts=false`
- 本地 2 CN / 1 TN / 1 Log
- 对照: MySQL 8.3.0

## 最小复现

```java
try (PreparedStatement ps = conn.prepareStatement("SELECT HEX(? & ?)")) {
ps.setBytes(1, new byte[]{0x12});
ps.setBytes(2, new byte[]{0x34});
ps.executeQuery();
}
```

期望和 MySQL 8.3 结果:`10`(`0x12 & 0x34 = 0x10`)。

MO 实际返回:`0`。

同一问题也影响 `|` 和 `^`:

| 参数 | 预期 / MySQL | MO |
| --- | --- | --- |
| `0x12 & 0x34` | `10` | `0` |
| `0x12 | 0x34` | `36` | `4` |
| `0x12 ^ 0x34` | `26` | `4` |
| `0xFF & 0x0F` | `0F` | `0` |
| `0xFF | 0x0F` | `FF` | `0` |
| `0xFF ^ 0x0F` | `F0` | `0` |

一元补码与移位也走数值域而非字节域:

| Prepared SQL / 参数 | 预期 / MySQL | MO |
| --- | --- | --- |
| `HEX(~?)`, `0x80` | `7F` | `FFFFFFFFFFFFFFFF` |
| `HEX(~?)`, `0x1234` | `EDCB` | `FFFFFFFFFFFFFFFF` |
| `HEX(? >> ?)`, `0x80, 1` | `40` | `0` |
| `HEX(? << ?)`, `0x1234, 8` | `3400` | `0` |

不等长参数也未被识别:

```java
ps.setBytes(1, new byte[]{0x01});
ps.setBytes(2, new byte[]{0x00, 0x01});
```

MySQL 返回 `ERROR 3513: Binary operands of bitwise operators must be of equal length`;MO 返回一个值(`0`),没有报错。

## 范围与对照

- `~`、`<<`、`>>`、`&`、`|`、`^` 均复现;每个操作在 CN1 上重复 3/3,MySQL 对照 3/3;
- 字面量 `_binary X'12' & _binary X'34'` 和等长表列值均返回正确字节结果,说明底层字节算子可用;
- 表列的不等长值会被拒绝,但当前误报为 20101 internal error;该错误分类问题单独跟踪,避免与 PreparedStatement 的错误结果混合;
- 已检查关闭的 #25246:它修复的是字面量/普通 binary-string 被错误走数值运算,本 issue 是其未覆盖的二进制协议参数路径。

## 预期行为

`setBytes()` 绑定到二进制协议参数后,应保留 binary-string domain,使 `&`、`|`、`^` 按字节逐位计算,保留长度;长度不同的两个操作数必须返回语义错误而不是计算数值结果。

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.