Bug #117750 | FORCE INDEX does not skip records_in_range() for 'x IS NOT NULL' | ||
---|---|---|---|
Submitted: | 19 Mar 11:46 | Modified: | 20 Mar 5:44 |
Reporter: | Kaiwang CHen (OCA) | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S3 (Non-critical) |
Version: | 8.0, 8.4, 9.2 | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | Contribution |
[19 Mar 11:46]
Kaiwang CHen
[19 Mar 11:50]
Kaiwang CHen
Check presence of the upper end in SEL_ARG::is_null_interval(). (*) I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.
Contribution: skip_records_in_range_crash_is_not_null.patch (application/octet-stream, text), 2.43 KiB.
[19 Mar 12:10]
MySQL Verification Team
Hello Kaiwang, Thank you for the report and contribution. regards, Umesh
[19 Mar 13:19]
Kaiwang CHen
BTW, the essentially same query does not call records_in_range(). EXPLAIN SELECT * FROM t1 FORCE INDEX(c1) WHERE c1 > 0; They create same (NULL, +Inf) range. The only difference is the NULL_RANGE flag: // NEAR_MIN | NO_MAX_RANGE | NULL_RANGE | SKIP_RECORDS_IN_RANGE = 582 EXPLAIN SELECT * FROM t1 FORCE INDEX(c1) WHERE c1 IS NOT NULL; // NEAR_MIN | NO_MAX_RANGE | SKIP_RECORDS_IN_RANGE = 518 EXPLAIN SELECT * FROM t1 FORCE INDEX(c1) WHERE c1 > 0;
[20 Mar 5:44]
Kaiwang CHen
BTW, an alternative fix is to test NO_MAX_RANGE before invoking is_null_interval() here, because any other usage site already guarantees !(max_flag & NO_MAX_RANGE). However, the comment of is_null_interval() suggests the way in the contributed patch. if (key_tree->is_null_interval()) push_position->min_key_flag |= NULL_RANGE;