# [Critical bug] TiDB 4.0:5.0:5.1 TiFlash执行过滤的结果不正确

## Issue

在 SQL 的 where 条件中含 “{常量} </<=/>/>= {列}”的情况下，TiFlash 可能将部分数据错误地剔除出查询结果，导致查询结果不正确。但是如果将常量放到比较操作符之后，改写为 “{列} </<=/>/>= {常量}” 的形式，查询结果是正确的。

SQL 的 where 语句中含有如下的过滤条件，通过 TiFlash 进行查询，就有可能触发：

比较符为 “<”/”<=”/”>”/”>=”

常量在比较符之前

列类型被加上了 not null 约束

列的数据类型为整数类型（TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT、BIT、BOOLEAN）或者日期类型（DATE、TIME、DATETIME、TIMESTAMP、YEAR）

## 影响版本

[v4.0.0~v4.0.14]

[v5.0.0~v5.0.3]

[v5.1.0~v5.1.1]

## 修复版本

v4.0.15

v5.0.4

v5.1.2

v5.2.0

## Root Cause

TiDB 将执行计划以及过滤条件生成 DAGRequest，发送到 TiFlash 进行处理。TiFlash 中为了将过滤条件下推到存储层，通过 chunk 的统计信息 (如 min-max) 减少不必要的 IO，会将 DAGRequst 中的 selection 算子，解析为 RoughSetFilter 并传到存储层的读取中。

在解析 selection 算子的时候，没有考虑到 “{常量} </<=/>/>= {列}” 对运算符的方向性的影响。 “1 > a” 的过滤条件会被错误地解析为 “a > 1” 的 RoughSetFilter，从而使得 TiFlash 存储层利用粗糙索引，对 stable 层数据进行过滤的时候，错误地将一些 chunk 排除在查询结果

## Diagnostic Steps

Oncall issue：

[ONCALL-3477](https://internal.pingcap.net/jira/browse/ONCALL-3477)

[ONCALL-3334](https://internal.pingcap.net/jira/browse/ONCALL-3334)

## Resolution

N/A

## Workaround

改写 SQL 语句，将 where 语句中 “{常量} </<=/>/>= {列}” 改为 “{列} </<=/>/>= {常量}”

或者通过修改 TiFlash 的 config 配置项，禁用粗糙索引过滤。注意如果禁用粗糙索引过滤，会导致一些场景下扫描大量不必要的数据，引起性能下降问题。在升级到修复的版本之后，需要将该配置项删除。

server_configs:
  tiflash:
    profiles.default.dt_enable_rough_set_filter: false
