Skip to content

enhance the filter propagation on is null #7973

@zz-jason

Description

@zz-jason

Feature Request

Is your feature request related to a problem? Please describe:

Relates to #7834

Describe the feature you'd like:

Let's say we have the following table:

drop table if exists t;
create table t(a bigint, b bigint);
insert into t values(1, 1), (null, null);

in the filters of a query, if there is a filter a is null, and column a is involved in another null rejective filter, e.g. a=b, a in (1, null), a > 10, then we can derive a false filter and further change the filters of the query to false, because there is no record can satisfy both the filters at the same time.

Examples in MySQL:

MySQL(localhost:3306) > select * from t where a is null and a=b;
Empty set (0.00 sec)

MySQL(localhost:3306) > select * from t where a is null and a in (1, null);
Empty set (0.00 sec)

MySQL(localhost:3306) > select * from t where a is null and a>10;
Empty set (0.00 sec)

Execution plans in TiDB:

TiDB(localhost:4000) > desc select * from t where a is null and a=b;
+---------------------+----------+------+------------------------------------------------------------+
| id                  | count    | task | operator info                                              |
+---------------------+----------+------+------------------------------------------------------------+
| TableReader_7       | 8.00     | root | data:Selection_6                                           |
| └─Selection_6       | 8.00     | cop  | eq(test.t.a, test.t.b), isnull(test.t.a)                   |
|   └─TableScan_5     | 10000.00 | cop  | table:t, range:[-inf,+inf], keep order:false, stats:pseudo |
+---------------------+----------+------+------------------------------------------------------------+
3 rows in set (0.00 sec)

TiDB(localhost:4000) > desc select * from t where a is null and a in (1, null);
+---------------------+----------+------+------------------------------------------------------------+
| id                  | count    | task | operator info                                              |
+---------------------+----------+------+------------------------------------------------------------+
| TableReader_7       | 0.00     | root | data:Selection_6                                           |
| └─Selection_6       | 0.00     | cop  | in(test.t.a, 1, NULL), isnull(test.t.a)                    |
|   └─TableScan_5     | 10000.00 | cop  | table:t, range:[-inf,+inf], keep order:false, stats:pseudo |
+---------------------+----------+------+------------------------------------------------------------+
3 rows in set (0.00 sec)

TiDB(localhost:4000) > desc select * from t where a is null and a>10;
+---------------------+----------+------+------------------------------------------------------------+
| id                  | count    | task | operator info                                              |
+---------------------+----------+------+------------------------------------------------------------+
| TableReader_7       | 0.00     | root | data:Selection_6                                           |
| └─Selection_6       | 0.00     | cop  | gt(test.t.a, 10), isnull(test.t.a)                         |
|   └─TableScan_5     | 10000.00 | cop  | table:t, range:[-inf,+inf], keep order:false, stats:pseudo |
+---------------------+----------+------+------------------------------------------------------------+
3 rows in set (0.00 sec)

TiDB(localhost:4000) > desc select * from t where a is null and a=10;
+---------------------+----------+------+------------------------------------------------------------+
| id                  | count    | task | operator info                                              |
+---------------------+----------+------+------------------------------------------------------------+
| TableReader_7       | 0.00     | root | data:Selection_6                                           |
| └─Selection_6       | 0.00     | cop  | eq(test.t.a, 10), isnull(test.t.a)                         |
|   └─TableScan_5     | 10000.00 | cop  | table:t, range:[-inf,+inf], keep order:false, stats:pseudo |
+---------------------+----------+------+------------------------------------------------------------+
3 rows in set (0.00 sec)

TiDB(localhost:4000) > select tidb_version()\G
*************************** 1. row ***************************
tidb_version(): Release Version: v2.1.0-rc.3-79-gedaec7bda
Git Commit Hash: edaec7bdaf7cdc7e1ba822e393112c2d592308ad
Git Branch: master
UTC Build Time: 2018-10-21 05:57:46
GoVersion: go version go1.11 darwin/amd64
Race Enabled: false
TiKV Min Version: 2.1.0-alpha.1-ff3dd160846b7d1aed9079c389fc188f7f5ea13e
Check Table Before Drop: false
1 row in set (0.00 sec)

Describe alternatives you've considered:
No

Teachability, Documentation, Adoption, Migration Strategy:
No

Metadata

Metadata

Labels

sig/plannerSIG: Plannertype/enhancementThe issue or PR belongs to an enhancement.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions